Statistics
| Branch: | Revision:

root / target-i386 / translate.c @ 321c5351

History | View | Annotate | Download (283.2 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, see <http://www.gnu.org/licenses/>.
18
 */
19
#include <stdarg.h>
20
#include <stdlib.h>
21
#include <stdio.h>
22
#include <string.h>
23
#include <inttypes.h>
24
#include <signal.h>
25

    
26
#include "qemu/host-utils.h"
27
#include "cpu.h"
28
#include "disas/disas.h"
29
#include "tcg-op.h"
30

    
31
#include "helper.h"
32
#define GEN_HELPER 1
33
#include "helper.h"
34

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

    
42
#ifdef TARGET_X86_64
43
#define CODE64(s) ((s)->code64)
44
#define REX_X(s) ((s)->rex_x)
45
#define REX_B(s) ((s)->rex_b)
46
#else
47
#define CODE64(s) 0
48
#define REX_X(s) 0
49
#define REX_B(s) 0
50
#endif
51

    
52
#ifdef TARGET_X86_64
53
# define ctztl  ctz64
54
# define clztl  clz64
55
#else
56
# define ctztl  ctz32
57
# define clztl  clz32
58
#endif
59

    
60
//#define MACRO_TEST   1
61

    
62
/* global register indexes */
63
static TCGv_ptr cpu_env;
64
static TCGv cpu_A0;
65
static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2, cpu_cc_srcT;
66
static TCGv_i32 cpu_cc_op;
67
static TCGv cpu_regs[CPU_NB_REGS];
68
/* local temps */
69
static TCGv cpu_T[2];
70
/* local register indexes (only used inside old micro ops) */
71
static TCGv cpu_tmp0, cpu_tmp4;
72
static TCGv_ptr cpu_ptr0, cpu_ptr1;
73
static TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32;
74
static TCGv_i64 cpu_tmp1_i64;
75
static TCGv cpu_tmp5;
76

    
77
static uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
78

    
79
#include "exec/gen-icount.h"
80

    
81
#ifdef TARGET_X86_64
82
static int x86_64_hregs;
83
#endif
84

    
85
typedef struct DisasContext {
86
    /* current insn context */
87
    int override; /* -1 if no override */
88
    int prefix;
89
    int aflag, dflag;
90
    target_ulong pc; /* pc = eip + cs_base */
91
    int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
92
                   static state change (stop translation) */
93
    /* current block context */
94
    target_ulong cs_base; /* base of CS segment */
95
    int pe;     /* protected mode */
96
    int code32; /* 32 bit code segment */
97
#ifdef TARGET_X86_64
98
    int lma;    /* long mode active */
99
    int code64; /* 64 bit code segment */
100
    int rex_x, rex_b;
101
#endif
102
    int vex_l;  /* vex vector length */
103
    int vex_v;  /* vex vvvv register, without 1's compliment.  */
104
    int ss32;   /* 32 bit stack segment */
105
    CCOp cc_op;  /* current CC operation */
106
    bool cc_op_dirty;
107
    int addseg; /* non zero if either DS/ES/SS have a non zero base */
108
    int f_st;   /* currently unused */
109
    int vm86;   /* vm86 mode */
110
    int cpl;
111
    int iopl;
112
    int tf;     /* TF cpu flag */
113
    int singlestep_enabled; /* "hardware" single step enabled */
114
    int jmp_opt; /* use direct block chaining for direct jumps */
115
    int mem_index; /* select memory access functions */
116
    uint64_t flags; /* all execution flags */
117
    struct TranslationBlock *tb;
118
    int popl_esp_hack; /* for correct popl with esp base handling */
119
    int rip_offset; /* only used in x86_64, but left for simplicity */
120
    int cpuid_features;
121
    int cpuid_ext_features;
122
    int cpuid_ext2_features;
123
    int cpuid_ext3_features;
124
    int cpuid_7_0_ebx_features;
125
} DisasContext;
126

    
127
static void gen_eob(DisasContext *s);
128
static void gen_jmp(DisasContext *s, target_ulong eip);
129
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
130
static void gen_op(DisasContext *s1, int op, int ot, int d);
131

    
132
/* i386 arith/logic operations */
133
enum {
134
    OP_ADDL,
135
    OP_ORL,
136
    OP_ADCL,
137
    OP_SBBL,
138
    OP_ANDL,
139
    OP_SUBL,
140
    OP_XORL,
141
    OP_CMPL,
142
};
143

    
144
/* i386 shift ops */
145
enum {
146
    OP_ROL,
147
    OP_ROR,
148
    OP_RCL,
149
    OP_RCR,
150
    OP_SHL,
151
    OP_SHR,
152
    OP_SHL1, /* undocumented */
153
    OP_SAR = 7,
154
};
155

    
156
enum {
157
    JCC_O,
158
    JCC_B,
159
    JCC_Z,
160
    JCC_BE,
161
    JCC_S,
162
    JCC_P,
163
    JCC_L,
164
    JCC_LE,
165
};
166

    
167
/* operand size */
168
enum {
169
    OT_BYTE = 0,
170
    OT_WORD,
171
    OT_LONG,
172
    OT_QUAD,
173
};
174

    
175
enum {
176
    /* I386 int registers */
177
    OR_EAX,   /* MUST be even numbered */
178
    OR_ECX,
179
    OR_EDX,
180
    OR_EBX,
181
    OR_ESP,
182
    OR_EBP,
183
    OR_ESI,
184
    OR_EDI,
185

    
186
    OR_TMP0 = 16,    /* temporary operand register */
187
    OR_TMP1,
188
    OR_A0, /* temporary register used when doing address evaluation */
189
};
190

    
191
enum {
192
    USES_CC_DST  = 1,
193
    USES_CC_SRC  = 2,
194
    USES_CC_SRC2 = 4,
195
    USES_CC_SRCT = 8,
196
};
197

    
198
/* Bit set if the global variable is live after setting CC_OP to X.  */
199
static const uint8_t cc_op_live[CC_OP_NB] = {
200
    [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
201
    [CC_OP_EFLAGS] = USES_CC_SRC,
202
    [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC,
203
    [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC,
204
    [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
205
    [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRCT,
206
    [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
207
    [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST,
208
    [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC,
209
    [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC,
210
    [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC,
211
    [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC,
212
    [CC_OP_BMILGB ... CC_OP_BMILGQ] = USES_CC_DST | USES_CC_SRC,
213
    [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC,
214
    [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2,
215
    [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
216
};
217

    
218
static void set_cc_op(DisasContext *s, CCOp op)
219
{
220
    int dead;
221

    
222
    if (s->cc_op == op) {
223
        return;
224
    }
225

    
226
    /* Discard CC computation that will no longer be used.  */
227
    dead = cc_op_live[s->cc_op] & ~cc_op_live[op];
228
    if (dead & USES_CC_DST) {
229
        tcg_gen_discard_tl(cpu_cc_dst);
230
    }
231
    if (dead & USES_CC_SRC) {
232
        tcg_gen_discard_tl(cpu_cc_src);
233
    }
234
    if (dead & USES_CC_SRC2) {
235
        tcg_gen_discard_tl(cpu_cc_src2);
236
    }
237
    if (dead & USES_CC_SRCT) {
238
        tcg_gen_discard_tl(cpu_cc_srcT);
239
    }
240

    
241
    s->cc_op = op;
242
    /* The DYNAMIC setting is translator only, and should never be
243
       stored.  Thus we always consider it clean.  */
244
    s->cc_op_dirty = (op != CC_OP_DYNAMIC);
245
}
246

    
247
static void gen_update_cc_op(DisasContext *s)
248
{
249
    if (s->cc_op_dirty) {
250
        tcg_gen_movi_i32(cpu_cc_op, s->cc_op);
251
        s->cc_op_dirty = false;
252
    }
253
}
254

    
255
static inline void gen_op_movl_T0_0(void)
256
{
257
    tcg_gen_movi_tl(cpu_T[0], 0);
258
}
259

    
260
static inline void gen_op_movl_T0_im(int32_t val)
261
{
262
    tcg_gen_movi_tl(cpu_T[0], val);
263
}
264

    
265
static inline void gen_op_movl_T0_imu(uint32_t val)
266
{
267
    tcg_gen_movi_tl(cpu_T[0], val);
268
}
269

    
270
static inline void gen_op_movl_T1_im(int32_t val)
271
{
272
    tcg_gen_movi_tl(cpu_T[1], val);
273
}
274

    
275
static inline void gen_op_movl_T1_imu(uint32_t val)
276
{
277
    tcg_gen_movi_tl(cpu_T[1], val);
278
}
279

    
280
static inline void gen_op_movl_A0_im(uint32_t val)
281
{
282
    tcg_gen_movi_tl(cpu_A0, val);
283
}
284

    
285
#ifdef TARGET_X86_64
286
static inline void gen_op_movq_A0_im(int64_t val)
287
{
288
    tcg_gen_movi_tl(cpu_A0, val);
289
}
290
#endif
291

    
292
static inline void gen_movtl_T0_im(target_ulong val)
293
{
294
    tcg_gen_movi_tl(cpu_T[0], val);
295
}
296

    
297
static inline void gen_movtl_T1_im(target_ulong val)
298
{
299
    tcg_gen_movi_tl(cpu_T[1], val);
300
}
301

    
302
static inline void gen_op_andl_T0_ffff(void)
303
{
304
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
305
}
306

    
307
static inline void gen_op_andl_T0_im(uint32_t val)
308
{
309
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], val);
310
}
311

    
312
static inline void gen_op_movl_T0_T1(void)
313
{
314
    tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
315
}
316

    
317
static inline void gen_op_andl_A0_ffff(void)
318
{
319
    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffff);
320
}
321

    
322
#ifdef TARGET_X86_64
323

    
324
#define NB_OP_SIZES 4
325

    
326
#else /* !TARGET_X86_64 */
327

    
328
#define NB_OP_SIZES 3
329

    
330
#endif /* !TARGET_X86_64 */
331

    
332
#if defined(HOST_WORDS_BIGENDIAN)
333
#define REG_B_OFFSET (sizeof(target_ulong) - 1)
334
#define REG_H_OFFSET (sizeof(target_ulong) - 2)
335
#define REG_W_OFFSET (sizeof(target_ulong) - 2)
336
#define REG_L_OFFSET (sizeof(target_ulong) - 4)
337
#define REG_LH_OFFSET (sizeof(target_ulong) - 8)
338
#else
339
#define REG_B_OFFSET 0
340
#define REG_H_OFFSET 1
341
#define REG_W_OFFSET 0
342
#define REG_L_OFFSET 0
343
#define REG_LH_OFFSET 4
344
#endif
345

    
346
/* In instruction encodings for byte register accesses the
347
 * register number usually indicates "low 8 bits of register N";
348
 * however there are some special cases where N 4..7 indicates
349
 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
350
 * true for this special case, false otherwise.
351
 */
352
static inline bool byte_reg_is_xH(int reg)
353
{
354
    if (reg < 4) {
355
        return false;
356
    }
357
#ifdef TARGET_X86_64
358
    if (reg >= 8 || x86_64_hregs) {
359
        return false;
360
    }
361
#endif
362
    return true;
363
}
364

    
365
static inline void gen_op_mov_reg_v(int ot, int reg, TCGv t0)
366
{
367
    switch(ot) {
368
    case OT_BYTE:
369
        if (!byte_reg_is_xH(reg)) {
370
            tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8);
371
        } else {
372
            tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8);
373
        }
374
        break;
375
    case OT_WORD:
376
        tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16);
377
        break;
378
    default: /* XXX this shouldn't be reached;  abort? */
379
    case OT_LONG:
380
        /* For x86_64, this sets the higher half of register to zero.
381
           For i386, this is equivalent to a mov. */
382
        tcg_gen_ext32u_tl(cpu_regs[reg], t0);
383
        break;
384
#ifdef TARGET_X86_64
385
    case OT_QUAD:
386
        tcg_gen_mov_tl(cpu_regs[reg], t0);
387
        break;
388
#endif
389
    }
390
}
391

    
392
static inline void gen_op_mov_reg_T0(int ot, int reg)
393
{
394
    gen_op_mov_reg_v(ot, reg, cpu_T[0]);
395
}
396

    
397
static inline void gen_op_mov_reg_T1(int ot, int reg)
398
{
399
    gen_op_mov_reg_v(ot, reg, cpu_T[1]);
400
}
401

    
402
static inline void gen_op_mov_reg_A0(int size, int reg)
403
{
404
    switch(size) {
405
    case OT_BYTE:
406
        tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_A0, 0, 16);
407
        break;
408
    default: /* XXX this shouldn't be reached;  abort? */
409
    case OT_WORD:
410
        /* For x86_64, this sets the higher half of register to zero.
411
           For i386, this is equivalent to a mov. */
412
        tcg_gen_ext32u_tl(cpu_regs[reg], cpu_A0);
413
        break;
414
#ifdef TARGET_X86_64
415
    case OT_LONG:
416
        tcg_gen_mov_tl(cpu_regs[reg], cpu_A0);
417
        break;
418
#endif
419
    }
420
}
421

    
422
static inline void gen_op_mov_v_reg(int ot, TCGv t0, int reg)
423
{
424
    if (ot == OT_BYTE && byte_reg_is_xH(reg)) {
425
        tcg_gen_shri_tl(t0, cpu_regs[reg - 4], 8);
426
        tcg_gen_ext8u_tl(t0, t0);
427
    } else {
428
        tcg_gen_mov_tl(t0, cpu_regs[reg]);
429
    }
430
}
431

    
432
static inline void gen_op_mov_TN_reg(int ot, int t_index, int reg)
433
{
434
    gen_op_mov_v_reg(ot, cpu_T[t_index], reg);
435
}
436

    
437
static inline void gen_op_movl_A0_reg(int reg)
438
{
439
    tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
440
}
441

    
442
static inline void gen_op_addl_A0_im(int32_t val)
443
{
444
    tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
445
#ifdef TARGET_X86_64
446
    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
447
#endif
448
}
449

    
450
#ifdef TARGET_X86_64
451
static inline void gen_op_addq_A0_im(int64_t val)
452
{
453
    tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
454
}
455
#endif
456
    
457
static void gen_add_A0_im(DisasContext *s, int val)
458
{
459
#ifdef TARGET_X86_64
460
    if (CODE64(s))
461
        gen_op_addq_A0_im(val);
462
    else
463
#endif
464
        gen_op_addl_A0_im(val);
465
}
466

    
467
static inline void gen_op_addl_T0_T1(void)
468
{
469
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
470
}
471

    
472
static inline void gen_op_jmp_T0(void)
473
{
474
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, eip));
475
}
476

    
477
static inline void gen_op_add_reg_im(int size, int reg, int32_t val)
478
{
479
    switch(size) {
480
    case OT_BYTE:
481
        tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
482
        tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0, 0, 16);
483
        break;
484
    case OT_WORD:
485
        tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
486
        /* For x86_64, this sets the higher half of register to zero.
487
           For i386, this is equivalent to a nop. */
488
        tcg_gen_ext32u_tl(cpu_tmp0, cpu_tmp0);
489
        tcg_gen_mov_tl(cpu_regs[reg], cpu_tmp0);
490
        break;
491
#ifdef TARGET_X86_64
492
    case OT_LONG:
493
        tcg_gen_addi_tl(cpu_regs[reg], cpu_regs[reg], val);
494
        break;
495
#endif
496
    }
497
}
498

    
499
static inline void gen_op_add_reg_T0(int size, int reg)
500
{
501
    switch(size) {
502
    case OT_BYTE:
503
        tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]);
504
        tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0, 0, 16);
505
        break;
506
    case OT_WORD:
507
        tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]);
508
        /* For x86_64, this sets the higher half of register to zero.
509
           For i386, this is equivalent to a nop. */
510
        tcg_gen_ext32u_tl(cpu_tmp0, cpu_tmp0);
511
        tcg_gen_mov_tl(cpu_regs[reg], cpu_tmp0);
512
        break;
513
#ifdef TARGET_X86_64
514
    case OT_LONG:
515
        tcg_gen_add_tl(cpu_regs[reg], cpu_regs[reg], cpu_T[0]);
516
        break;
517
#endif
518
    }
519
}
520

    
521
static inline void gen_op_addl_A0_reg_sN(int shift, int reg)
522
{
523
    tcg_gen_mov_tl(cpu_tmp0, cpu_regs[reg]);
524
    if (shift != 0)
525
        tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
526
    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
527
    /* For x86_64, this sets the higher half of register to zero.
528
       For i386, this is equivalent to a nop. */
529
    tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
530
}
531

    
532
static inline void gen_op_movl_A0_seg(int reg)
533
{
534
    tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUX86State, segs[reg].base) + REG_L_OFFSET);
535
}
536

    
537
static inline void gen_op_addl_A0_seg(DisasContext *s, int reg)
538
{
539
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, segs[reg].base));
540
#ifdef TARGET_X86_64
541
    if (CODE64(s)) {
542
        tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
543
        tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
544
    } else {
545
        tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
546
        tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
547
    }
548
#else
549
    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
550
#endif
551
}
552

    
553
#ifdef TARGET_X86_64
554
static inline void gen_op_movq_A0_seg(int reg)
555
{
556
    tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUX86State, segs[reg].base));
557
}
558

    
559
static inline void gen_op_addq_A0_seg(int reg)
560
{
561
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, segs[reg].base));
562
    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
563
}
564

    
565
static inline void gen_op_movq_A0_reg(int reg)
566
{
567
    tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
568
}
569

    
570
static inline void gen_op_addq_A0_reg_sN(int shift, int reg)
571
{
572
    tcg_gen_mov_tl(cpu_tmp0, cpu_regs[reg]);
573
    if (shift != 0)
574
        tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
575
    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
576
}
577
#endif
578

    
579
static inline void gen_op_lds_T0_A0(int idx)
580
{
581
    int mem_index = (idx >> 2) - 1;
582
    switch(idx & 3) {
583
    case OT_BYTE:
584
        tcg_gen_qemu_ld8s(cpu_T[0], cpu_A0, mem_index);
585
        break;
586
    case OT_WORD:
587
        tcg_gen_qemu_ld16s(cpu_T[0], cpu_A0, mem_index);
588
        break;
589
    default:
590
    case OT_LONG:
591
        tcg_gen_qemu_ld32s(cpu_T[0], cpu_A0, mem_index);
592
        break;
593
    }
594
}
595

    
596
static inline void gen_op_ld_v(int idx, TCGv t0, TCGv a0)
597
{
598
    int mem_index = (idx >> 2) - 1;
599
    switch(idx & 3) {
600
    case OT_BYTE:
601
        tcg_gen_qemu_ld8u(t0, a0, mem_index);
602
        break;
603
    case OT_WORD:
604
        tcg_gen_qemu_ld16u(t0, a0, mem_index);
605
        break;
606
    case OT_LONG:
607
        tcg_gen_qemu_ld32u(t0, a0, mem_index);
608
        break;
609
    default:
610
    case OT_QUAD:
611
        /* Should never happen on 32-bit targets.  */
612
#ifdef TARGET_X86_64
613
        tcg_gen_qemu_ld64(t0, a0, mem_index);
614
#endif
615
        break;
616
    }
617
}
618

    
619
/* XXX: always use ldu or lds */
620
static inline void gen_op_ld_T0_A0(int idx)
621
{
622
    gen_op_ld_v(idx, cpu_T[0], cpu_A0);
623
}
624

    
625
static inline void gen_op_ldu_T0_A0(int idx)
626
{
627
    gen_op_ld_v(idx, cpu_T[0], cpu_A0);
628
}
629

    
630
static inline void gen_op_ld_T1_A0(int idx)
631
{
632
    gen_op_ld_v(idx, cpu_T[1], cpu_A0);
633
}
634

    
635
static inline void gen_op_st_v(int idx, TCGv t0, TCGv a0)
636
{
637
    int mem_index = (idx >> 2) - 1;
638
    switch(idx & 3) {
639
    case OT_BYTE:
640
        tcg_gen_qemu_st8(t0, a0, mem_index);
641
        break;
642
    case OT_WORD:
643
        tcg_gen_qemu_st16(t0, a0, mem_index);
644
        break;
645
    case OT_LONG:
646
        tcg_gen_qemu_st32(t0, a0, mem_index);
647
        break;
648
    default:
649
    case OT_QUAD:
650
        /* Should never happen on 32-bit targets.  */
651
#ifdef TARGET_X86_64
652
        tcg_gen_qemu_st64(t0, a0, mem_index);
653
#endif
654
        break;
655
    }
656
}
657

    
658
static inline void gen_op_st_T0_A0(int idx)
659
{
660
    gen_op_st_v(idx, cpu_T[0], cpu_A0);
661
}
662

    
663
static inline void gen_op_st_T1_A0(int idx)
664
{
665
    gen_op_st_v(idx, cpu_T[1], cpu_A0);
666
}
667

    
668
static inline void gen_jmp_im(target_ulong pc)
669
{
670
    tcg_gen_movi_tl(cpu_tmp0, pc);
671
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, eip));
672
}
673

    
674
static inline void gen_string_movl_A0_ESI(DisasContext *s)
675
{
676
    int override;
677

    
678
    override = s->override;
679
#ifdef TARGET_X86_64
680
    if (s->aflag == 2) {
681
        if (override >= 0) {
682
            gen_op_movq_A0_seg(override);
683
            gen_op_addq_A0_reg_sN(0, R_ESI);
684
        } else {
685
            gen_op_movq_A0_reg(R_ESI);
686
        }
687
    } else
688
#endif
689
    if (s->aflag) {
690
        /* 32 bit address */
691
        if (s->addseg && override < 0)
692
            override = R_DS;
693
        if (override >= 0) {
694
            gen_op_movl_A0_seg(override);
695
            gen_op_addl_A0_reg_sN(0, R_ESI);
696
        } else {
697
            gen_op_movl_A0_reg(R_ESI);
698
        }
699
    } else {
700
        /* 16 address, always override */
701
        if (override < 0)
702
            override = R_DS;
703
        gen_op_movl_A0_reg(R_ESI);
704
        gen_op_andl_A0_ffff();
705
        gen_op_addl_A0_seg(s, override);
706
    }
707
}
708

    
709
static inline void gen_string_movl_A0_EDI(DisasContext *s)
710
{
711
#ifdef TARGET_X86_64
712
    if (s->aflag == 2) {
713
        gen_op_movq_A0_reg(R_EDI);
714
    } else
715
#endif
716
    if (s->aflag) {
717
        if (s->addseg) {
718
            gen_op_movl_A0_seg(R_ES);
719
            gen_op_addl_A0_reg_sN(0, R_EDI);
720
        } else {
721
            gen_op_movl_A0_reg(R_EDI);
722
        }
723
    } else {
724
        gen_op_movl_A0_reg(R_EDI);
725
        gen_op_andl_A0_ffff();
726
        gen_op_addl_A0_seg(s, R_ES);
727
    }
728
}
729

    
730
static inline void gen_op_movl_T0_Dshift(int ot) 
731
{
732
    tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, df));
733
    tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot);
734
};
735

    
736
static TCGv gen_ext_tl(TCGv dst, TCGv src, int size, bool sign)
737
{
738
    switch (size) {
739
    case OT_BYTE:
740
        if (sign) {
741
            tcg_gen_ext8s_tl(dst, src);
742
        } else {
743
            tcg_gen_ext8u_tl(dst, src);
744
        }
745
        return dst;
746
    case OT_WORD:
747
        if (sign) {
748
            tcg_gen_ext16s_tl(dst, src);
749
        } else {
750
            tcg_gen_ext16u_tl(dst, src);
751
        }
752
        return dst;
753
#ifdef TARGET_X86_64
754
    case OT_LONG:
755
        if (sign) {
756
            tcg_gen_ext32s_tl(dst, src);
757
        } else {
758
            tcg_gen_ext32u_tl(dst, src);
759
        }
760
        return dst;
761
#endif
762
    default:
763
        return src;
764
    }
765
}
766

    
767
static void gen_extu(int ot, TCGv reg)
768
{
769
    gen_ext_tl(reg, reg, ot, false);
770
}
771

    
772
static void gen_exts(int ot, TCGv reg)
773
{
774
    gen_ext_tl(reg, reg, ot, true);
775
}
776

    
777
static inline void gen_op_jnz_ecx(int size, int label1)
778
{
779
    tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
780
    gen_extu(size + 1, cpu_tmp0);
781
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
782
}
783

    
784
static inline void gen_op_jz_ecx(int size, int label1)
785
{
786
    tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
787
    gen_extu(size + 1, cpu_tmp0);
788
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
789
}
790

    
791
static void gen_helper_in_func(int ot, TCGv v, TCGv_i32 n)
792
{
793
    switch (ot) {
794
    case OT_BYTE:
795
        gen_helper_inb(v, n);
796
        break;
797
    case OT_WORD:
798
        gen_helper_inw(v, n);
799
        break;
800
    case OT_LONG:
801
        gen_helper_inl(v, n);
802
        break;
803
    }
804
}
805

    
806
static void gen_helper_out_func(int ot, TCGv_i32 v, TCGv_i32 n)
807
{
808
    switch (ot) {
809
    case OT_BYTE:
810
        gen_helper_outb(v, n);
811
        break;
812
    case OT_WORD:
813
        gen_helper_outw(v, n);
814
        break;
815
    case OT_LONG:
816
        gen_helper_outl(v, n);
817
        break;
818
    }
819
}
820

    
821
static void gen_check_io(DisasContext *s, int ot, target_ulong cur_eip,
822
                         uint32_t svm_flags)
823
{
824
    int state_saved;
825
    target_ulong next_eip;
826

    
827
    state_saved = 0;
828
    if (s->pe && (s->cpl > s->iopl || s->vm86)) {
829
        gen_update_cc_op(s);
830
        gen_jmp_im(cur_eip);
831
        state_saved = 1;
832
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
833
        switch (ot) {
834
        case OT_BYTE:
835
            gen_helper_check_iob(cpu_env, cpu_tmp2_i32);
836
            break;
837
        case OT_WORD:
838
            gen_helper_check_iow(cpu_env, cpu_tmp2_i32);
839
            break;
840
        case OT_LONG:
841
            gen_helper_check_iol(cpu_env, cpu_tmp2_i32);
842
            break;
843
        }
844
    }
845
    if(s->flags & HF_SVMI_MASK) {
846
        if (!state_saved) {
847
            gen_update_cc_op(s);
848
            gen_jmp_im(cur_eip);
849
        }
850
        svm_flags |= (1 << (4 + ot));
851
        next_eip = s->pc - s->cs_base;
852
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
853
        gen_helper_svm_check_io(cpu_env, cpu_tmp2_i32,
854
                                tcg_const_i32(svm_flags),
855
                                tcg_const_i32(next_eip - cur_eip));
856
    }
857
}
858

    
859
static inline void gen_movs(DisasContext *s, int ot)
860
{
861
    gen_string_movl_A0_ESI(s);
862
    gen_op_ld_T0_A0(ot + s->mem_index);
863
    gen_string_movl_A0_EDI(s);
864
    gen_op_st_T0_A0(ot + s->mem_index);
865
    gen_op_movl_T0_Dshift(ot);
866
    gen_op_add_reg_T0(s->aflag, R_ESI);
867
    gen_op_add_reg_T0(s->aflag, R_EDI);
868
}
869

    
870
static void gen_op_update1_cc(void)
871
{
872
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
873
}
874

    
875
static void gen_op_update2_cc(void)
876
{
877
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
878
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
879
}
880

    
881
static void gen_op_update3_cc(TCGv reg)
882
{
883
    tcg_gen_mov_tl(cpu_cc_src2, reg);
884
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
885
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
886
}
887

    
888
static inline void gen_op_testl_T0_T1_cc(void)
889
{
890
    tcg_gen_and_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
891
}
892

    
893
static void gen_op_update_neg_cc(void)
894
{
895
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
896
    tcg_gen_neg_tl(cpu_cc_src, cpu_T[0]);
897
    tcg_gen_movi_tl(cpu_cc_srcT, 0);
898
}
899

    
900
/* compute all eflags to cc_src */
901
static void gen_compute_eflags(DisasContext *s)
902
{
903
    TCGv zero, dst, src1, src2;
904
    int live, dead;
905

    
906
    if (s->cc_op == CC_OP_EFLAGS) {
907
        return;
908
    }
909

    
910
    TCGV_UNUSED(zero);
911
    dst = cpu_cc_dst;
912
    src1 = cpu_cc_src;
913
    src2 = cpu_cc_src2;
914

    
915
    /* Take care to not read values that are not live.  */
916
    live = cc_op_live[s->cc_op] & ~USES_CC_SRCT;
917
    dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2);
918
    if (dead) {
919
        zero = tcg_const_tl(0);
920
        if (dead & USES_CC_DST) {
921
            dst = zero;
922
        }
923
        if (dead & USES_CC_SRC) {
924
            src1 = zero;
925
        }
926
        if (dead & USES_CC_SRC2) {
927
            src2 = zero;
928
        }
929
    }
930

    
931
    gen_update_cc_op(s);
932
    gen_helper_cc_compute_all(cpu_cc_src, dst, src1, src2, cpu_cc_op);
933
    set_cc_op(s, CC_OP_EFLAGS);
934

    
935
    if (dead) {
936
        tcg_temp_free(zero);
937
    }
938
}
939

    
940
typedef struct CCPrepare {
941
    TCGCond cond;
942
    TCGv reg;
943
    TCGv reg2;
944
    target_ulong imm;
945
    target_ulong mask;
946
    bool use_reg2;
947
    bool no_setcond;
948
} CCPrepare;
949

    
950
/* compute eflags.C to reg */
951
static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
952
{
953
    TCGv t0, t1;
954
    int size, shift;
955

    
956
    switch (s->cc_op) {
957
    case CC_OP_SUBB ... CC_OP_SUBQ:
958
        /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
959
        size = s->cc_op - CC_OP_SUBB;
960
        t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
961
        /* If no temporary was used, be careful not to alias t1 and t0.  */
962
        t0 = TCGV_EQUAL(t1, cpu_cc_src) ? cpu_tmp0 : reg;
963
        tcg_gen_mov_tl(t0, cpu_cc_srcT);
964
        gen_extu(size, t0);
965
        goto add_sub;
966

    
967
    case CC_OP_ADDB ... CC_OP_ADDQ:
968
        /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
969
        size = s->cc_op - CC_OP_ADDB;
970
        t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
971
        t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
972
    add_sub:
973
        return (CCPrepare) { .cond = TCG_COND_LTU, .reg = t0,
974
                             .reg2 = t1, .mask = -1, .use_reg2 = true };
975

    
976
    case CC_OP_LOGICB ... CC_OP_LOGICQ:
977
        return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
978

    
979
    case CC_OP_INCB ... CC_OP_INCQ:
980
    case CC_OP_DECB ... CC_OP_DECQ:
981
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
982
                             .mask = -1, .no_setcond = true };
983

    
984
    case CC_OP_SHLB ... CC_OP_SHLQ:
985
        /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
986
        size = s->cc_op - CC_OP_SHLB;
987
        shift = (8 << size) - 1;
988
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
989
                             .mask = (target_ulong)1 << shift };
990

    
991
    case CC_OP_MULB ... CC_OP_MULQ:
992
        return (CCPrepare) { .cond = TCG_COND_NE,
993
                             .reg = cpu_cc_src, .mask = -1 };
994

    
995
    case CC_OP_BMILGB ... CC_OP_BMILGQ:
996
        size = s->cc_op - CC_OP_BMILGB;
997
        t0 = gen_ext_tl(reg, cpu_cc_src, size, false);
998
        return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
999

    
1000
    case CC_OP_ADCX:
1001
    case CC_OP_ADCOX:
1002
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst,
1003
                             .mask = -1, .no_setcond = true };
1004

    
1005
    case CC_OP_EFLAGS:
1006
    case CC_OP_SARB ... CC_OP_SARQ:
1007
        /* CC_SRC & 1 */
1008
        return (CCPrepare) { .cond = TCG_COND_NE,
1009
                             .reg = cpu_cc_src, .mask = CC_C };
1010

    
1011
    default:
1012
       /* The need to compute only C from CC_OP_DYNAMIC is important
1013
          in efficiently implementing e.g. INC at the start of a TB.  */
1014
       gen_update_cc_op(s);
1015
       gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src,
1016
                               cpu_cc_src2, cpu_cc_op);
1017
       return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
1018
                            .mask = -1, .no_setcond = true };
1019
    }
1020
}
1021

    
1022
/* compute eflags.P to reg */
1023
static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg)
1024
{
1025
    gen_compute_eflags(s);
1026
    return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1027
                         .mask = CC_P };
1028
}
1029

    
1030
/* compute eflags.S to reg */
1031
static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg)
1032
{
1033
    switch (s->cc_op) {
1034
    case CC_OP_DYNAMIC:
1035
        gen_compute_eflags(s);
1036
        /* FALLTHRU */
1037
    case CC_OP_EFLAGS:
1038
    case CC_OP_ADCX:
1039
    case CC_OP_ADOX:
1040
    case CC_OP_ADCOX:
1041
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1042
                             .mask = CC_S };
1043
    default:
1044
        {
1045
            int size = (s->cc_op - CC_OP_ADDB) & 3;
1046
            TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true);
1047
            return (CCPrepare) { .cond = TCG_COND_LT, .reg = t0, .mask = -1 };
1048
        }
1049
    }
1050
}
1051

    
1052
/* compute eflags.O to reg */
1053
static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg)
1054
{
1055
    switch (s->cc_op) {
1056
    case CC_OP_ADOX:
1057
    case CC_OP_ADCOX:
1058
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2,
1059
                             .mask = -1, .no_setcond = true };
1060

    
1061
    default:
1062
        gen_compute_eflags(s);
1063
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1064
                             .mask = CC_O };
1065
    }
1066
}
1067

    
1068
/* compute eflags.Z to reg */
1069
static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg)
1070
{
1071
    switch (s->cc_op) {
1072
    case CC_OP_DYNAMIC:
1073
        gen_compute_eflags(s);
1074
        /* FALLTHRU */
1075
    case CC_OP_EFLAGS:
1076
    case CC_OP_ADCX:
1077
    case CC_OP_ADOX:
1078
    case CC_OP_ADCOX:
1079
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1080
                             .mask = CC_Z };
1081
    default:
1082
        {
1083
            int size = (s->cc_op - CC_OP_ADDB) & 3;
1084
            TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
1085
            return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
1086
        }
1087
    }
1088
}
1089

    
1090
/* perform a conditional store into register 'reg' according to jump opcode
1091
   value 'b'. In the fast case, T0 is guaranted not to be used. */
1092
static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
1093
{
1094
    int inv, jcc_op, size, cond;
1095
    CCPrepare cc;
1096
    TCGv t0;
1097

    
1098
    inv = b & 1;
1099
    jcc_op = (b >> 1) & 7;
1100

    
1101
    switch (s->cc_op) {
1102
    case CC_OP_SUBB ... CC_OP_SUBQ:
1103
        /* We optimize relational operators for the cmp/jcc case.  */
1104
        size = s->cc_op - CC_OP_SUBB;
1105
        switch (jcc_op) {
1106
        case JCC_BE:
1107
            tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
1108
            gen_extu(size, cpu_tmp4);
1109
            t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
1110
            cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = cpu_tmp4,
1111
                               .reg2 = t0, .mask = -1, .use_reg2 = true };
1112
            break;
1113

    
1114
        case JCC_L:
1115
            cond = TCG_COND_LT;
1116
            goto fast_jcc_l;
1117
        case JCC_LE:
1118
            cond = TCG_COND_LE;
1119
        fast_jcc_l:
1120
            tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
1121
            gen_exts(size, cpu_tmp4);
1122
            t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, true);
1123
            cc = (CCPrepare) { .cond = cond, .reg = cpu_tmp4,
1124
                               .reg2 = t0, .mask = -1, .use_reg2 = true };
1125
            break;
1126

    
1127
        default:
1128
            goto slow_jcc;
1129
        }
1130
        break;
1131

    
1132
    default:
1133
    slow_jcc:
1134
        /* This actually generates good code for JC, JZ and JS.  */
1135
        switch (jcc_op) {
1136
        case JCC_O:
1137
            cc = gen_prepare_eflags_o(s, reg);
1138
            break;
1139
        case JCC_B:
1140
            cc = gen_prepare_eflags_c(s, reg);
1141
            break;
1142
        case JCC_Z:
1143
            cc = gen_prepare_eflags_z(s, reg);
1144
            break;
1145
        case JCC_BE:
1146
            gen_compute_eflags(s);
1147
            cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1148
                               .mask = CC_Z | CC_C };
1149
            break;
1150
        case JCC_S:
1151
            cc = gen_prepare_eflags_s(s, reg);
1152
            break;
1153
        case JCC_P:
1154
            cc = gen_prepare_eflags_p(s, reg);
1155
            break;
1156
        case JCC_L:
1157
            gen_compute_eflags(s);
1158
            if (TCGV_EQUAL(reg, cpu_cc_src)) {
1159
                reg = cpu_tmp0;
1160
            }
1161
            tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
1162
            tcg_gen_xor_tl(reg, reg, cpu_cc_src);
1163
            cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
1164
                               .mask = CC_S };
1165
            break;
1166
        default:
1167
        case JCC_LE:
1168
            gen_compute_eflags(s);
1169
            if (TCGV_EQUAL(reg, cpu_cc_src)) {
1170
                reg = cpu_tmp0;
1171
            }
1172
            tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
1173
            tcg_gen_xor_tl(reg, reg, cpu_cc_src);
1174
            cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
1175
                               .mask = CC_S | CC_Z };
1176
            break;
1177
        }
1178
        break;
1179
    }
1180

    
1181
    if (inv) {
1182
        cc.cond = tcg_invert_cond(cc.cond);
1183
    }
1184
    return cc;
1185
}
1186

    
1187
static void gen_setcc1(DisasContext *s, int b, TCGv reg)
1188
{
1189
    CCPrepare cc = gen_prepare_cc(s, b, reg);
1190

    
1191
    if (cc.no_setcond) {
1192
        if (cc.cond == TCG_COND_EQ) {
1193
            tcg_gen_xori_tl(reg, cc.reg, 1);
1194
        } else {
1195
            tcg_gen_mov_tl(reg, cc.reg);
1196
        }
1197
        return;
1198
    }
1199

    
1200
    if (cc.cond == TCG_COND_NE && !cc.use_reg2 && cc.imm == 0 &&
1201
        cc.mask != 0 && (cc.mask & (cc.mask - 1)) == 0) {
1202
        tcg_gen_shri_tl(reg, cc.reg, ctztl(cc.mask));
1203
        tcg_gen_andi_tl(reg, reg, 1);
1204
        return;
1205
    }
1206
    if (cc.mask != -1) {
1207
        tcg_gen_andi_tl(reg, cc.reg, cc.mask);
1208
        cc.reg = reg;
1209
    }
1210
    if (cc.use_reg2) {
1211
        tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1212
    } else {
1213
        tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm);
1214
    }
1215
}
1216

    
1217
static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg)
1218
{
1219
    gen_setcc1(s, JCC_B << 1, reg);
1220
}
1221

    
1222
/* generate a conditional jump to label 'l1' according to jump opcode
1223
   value 'b'. In the fast case, T0 is guaranted not to be used. */
1224
static inline void gen_jcc1_noeob(DisasContext *s, int b, int l1)
1225
{
1226
    CCPrepare cc = gen_prepare_cc(s, b, cpu_T[0]);
1227

    
1228
    if (cc.mask != -1) {
1229
        tcg_gen_andi_tl(cpu_T[0], cc.reg, cc.mask);
1230
        cc.reg = cpu_T[0];
1231
    }
1232
    if (cc.use_reg2) {
1233
        tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1234
    } else {
1235
        tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1236
    }
1237
}
1238

    
1239
/* Generate a conditional jump to label 'l1' according to jump opcode
1240
   value 'b'. In the fast case, T0 is guaranted not to be used.
1241
   A translation block must end soon.  */
1242
static inline void gen_jcc1(DisasContext *s, int b, int l1)
1243
{
1244
    CCPrepare cc = gen_prepare_cc(s, b, cpu_T[0]);
1245

    
1246
    gen_update_cc_op(s);
1247
    if (cc.mask != -1) {
1248
        tcg_gen_andi_tl(cpu_T[0], cc.reg, cc.mask);
1249
        cc.reg = cpu_T[0];
1250
    }
1251
    set_cc_op(s, CC_OP_DYNAMIC);
1252
    if (cc.use_reg2) {
1253
        tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1254
    } else {
1255
        tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1256
    }
1257
}
1258

    
1259
/* XXX: does not work with gdbstub "ice" single step - not a
1260
   serious problem */
1261
static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
1262
{
1263
    int l1, l2;
1264

    
1265
    l1 = gen_new_label();
1266
    l2 = gen_new_label();
1267
    gen_op_jnz_ecx(s->aflag, l1);
1268
    gen_set_label(l2);
1269
    gen_jmp_tb(s, next_eip, 1);
1270
    gen_set_label(l1);
1271
    return l2;
1272
}
1273

    
1274
static inline void gen_stos(DisasContext *s, int ot)
1275
{
1276
    gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
1277
    gen_string_movl_A0_EDI(s);
1278
    gen_op_st_T0_A0(ot + s->mem_index);
1279
    gen_op_movl_T0_Dshift(ot);
1280
    gen_op_add_reg_T0(s->aflag, R_EDI);
1281
}
1282

    
1283
static inline void gen_lods(DisasContext *s, int ot)
1284
{
1285
    gen_string_movl_A0_ESI(s);
1286
    gen_op_ld_T0_A0(ot + s->mem_index);
1287
    gen_op_mov_reg_T0(ot, R_EAX);
1288
    gen_op_movl_T0_Dshift(ot);
1289
    gen_op_add_reg_T0(s->aflag, R_ESI);
1290
}
1291

    
1292
static inline void gen_scas(DisasContext *s, int ot)
1293
{
1294
    gen_string_movl_A0_EDI(s);
1295
    gen_op_ld_T1_A0(ot + s->mem_index);
1296
    gen_op(s, OP_CMPL, ot, R_EAX);
1297
    gen_op_movl_T0_Dshift(ot);
1298
    gen_op_add_reg_T0(s->aflag, R_EDI);
1299
}
1300

    
1301
static inline void gen_cmps(DisasContext *s, int ot)
1302
{
1303
    gen_string_movl_A0_EDI(s);
1304
    gen_op_ld_T1_A0(ot + s->mem_index);
1305
    gen_string_movl_A0_ESI(s);
1306
    gen_op(s, OP_CMPL, ot, OR_TMP0);
1307
    gen_op_movl_T0_Dshift(ot);
1308
    gen_op_add_reg_T0(s->aflag, R_ESI);
1309
    gen_op_add_reg_T0(s->aflag, R_EDI);
1310
}
1311

    
1312
static inline void gen_ins(DisasContext *s, int ot)
1313
{
1314
    if (use_icount)
1315
        gen_io_start();
1316
    gen_string_movl_A0_EDI(s);
1317
    /* Note: we must do this dummy write first to be restartable in
1318
       case of page fault. */
1319
    gen_op_movl_T0_0();
1320
    gen_op_st_T0_A0(ot + s->mem_index);
1321
    gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
1322
    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
1323
    tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1324
    gen_helper_in_func(ot, cpu_T[0], cpu_tmp2_i32);
1325
    gen_op_st_T0_A0(ot + s->mem_index);
1326
    gen_op_movl_T0_Dshift(ot);
1327
    gen_op_add_reg_T0(s->aflag, R_EDI);
1328
    if (use_icount)
1329
        gen_io_end();
1330
}
1331

    
1332
static inline void gen_outs(DisasContext *s, int ot)
1333
{
1334
    if (use_icount)
1335
        gen_io_start();
1336
    gen_string_movl_A0_ESI(s);
1337
    gen_op_ld_T0_A0(ot + s->mem_index);
1338

    
1339
    gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
1340
    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
1341
    tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1342
    tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]);
1343
    gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
1344

    
1345
    gen_op_movl_T0_Dshift(ot);
1346
    gen_op_add_reg_T0(s->aflag, R_ESI);
1347
    if (use_icount)
1348
        gen_io_end();
1349
}
1350

    
1351
/* same method as Valgrind : we generate jumps to current or next
1352
   instruction */
1353
#define GEN_REPZ(op)                                                          \
1354
static inline void gen_repz_ ## op(DisasContext *s, int ot,                   \
1355
                                 target_ulong cur_eip, target_ulong next_eip) \
1356
{                                                                             \
1357
    int l2;\
1358
    gen_update_cc_op(s);                                                      \
1359
    l2 = gen_jz_ecx_string(s, next_eip);                                      \
1360
    gen_ ## op(s, ot);                                                        \
1361
    gen_op_add_reg_im(s->aflag, R_ECX, -1);                                   \
1362
    /* a loop would cause two single step exceptions if ECX = 1               \
1363
       before rep string_insn */                                              \
1364
    if (!s->jmp_opt)                                                          \
1365
        gen_op_jz_ecx(s->aflag, l2);                                          \
1366
    gen_jmp(s, cur_eip);                                                      \
1367
}
1368

    
1369
#define GEN_REPZ2(op)                                                         \
1370
static inline void gen_repz_ ## op(DisasContext *s, int ot,                   \
1371
                                   target_ulong cur_eip,                      \
1372
                                   target_ulong next_eip,                     \
1373
                                   int nz)                                    \
1374
{                                                                             \
1375
    int l2;\
1376
    gen_update_cc_op(s);                                                      \
1377
    l2 = gen_jz_ecx_string(s, next_eip);                                      \
1378
    gen_ ## op(s, ot);                                                        \
1379
    gen_op_add_reg_im(s->aflag, R_ECX, -1);                                   \
1380
    gen_update_cc_op(s);                                                      \
1381
    gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2);                                 \
1382
    if (!s->jmp_opt)                                                          \
1383
        gen_op_jz_ecx(s->aflag, l2);                                          \
1384
    gen_jmp(s, cur_eip);                                                      \
1385
}
1386

    
1387
GEN_REPZ(movs)
1388
GEN_REPZ(stos)
1389
GEN_REPZ(lods)
1390
GEN_REPZ(ins)
1391
GEN_REPZ(outs)
1392
GEN_REPZ2(scas)
1393
GEN_REPZ2(cmps)
1394

    
1395
static void gen_helper_fp_arith_ST0_FT0(int op)
1396
{
1397
    switch (op) {
1398
    case 0:
1399
        gen_helper_fadd_ST0_FT0(cpu_env);
1400
        break;
1401
    case 1:
1402
        gen_helper_fmul_ST0_FT0(cpu_env);
1403
        break;
1404
    case 2:
1405
        gen_helper_fcom_ST0_FT0(cpu_env);
1406
        break;
1407
    case 3:
1408
        gen_helper_fcom_ST0_FT0(cpu_env);
1409
        break;
1410
    case 4:
1411
        gen_helper_fsub_ST0_FT0(cpu_env);
1412
        break;
1413
    case 5:
1414
        gen_helper_fsubr_ST0_FT0(cpu_env);
1415
        break;
1416
    case 6:
1417
        gen_helper_fdiv_ST0_FT0(cpu_env);
1418
        break;
1419
    case 7:
1420
        gen_helper_fdivr_ST0_FT0(cpu_env);
1421
        break;
1422
    }
1423
}
1424

    
1425
/* NOTE the exception in "r" op ordering */
1426
static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1427
{
1428
    TCGv_i32 tmp = tcg_const_i32(opreg);
1429
    switch (op) {
1430
    case 0:
1431
        gen_helper_fadd_STN_ST0(cpu_env, tmp);
1432
        break;
1433
    case 1:
1434
        gen_helper_fmul_STN_ST0(cpu_env, tmp);
1435
        break;
1436
    case 4:
1437
        gen_helper_fsubr_STN_ST0(cpu_env, tmp);
1438
        break;
1439
    case 5:
1440
        gen_helper_fsub_STN_ST0(cpu_env, tmp);
1441
        break;
1442
    case 6:
1443
        gen_helper_fdivr_STN_ST0(cpu_env, tmp);
1444
        break;
1445
    case 7:
1446
        gen_helper_fdiv_STN_ST0(cpu_env, tmp);
1447
        break;
1448
    }
1449
}
1450

    
1451
/* if d == OR_TMP0, it means memory operand (address in A0) */
1452
static void gen_op(DisasContext *s1, int op, int ot, int d)
1453
{
1454
    if (d != OR_TMP0) {
1455
        gen_op_mov_TN_reg(ot, 0, d);
1456
    } else {
1457
        gen_op_ld_T0_A0(ot + s1->mem_index);
1458
    }
1459
    switch(op) {
1460
    case OP_ADCL:
1461
        gen_compute_eflags_c(s1, cpu_tmp4);
1462
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1463
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
1464
        if (d != OR_TMP0)
1465
            gen_op_mov_reg_T0(ot, d);
1466
        else
1467
            gen_op_st_T0_A0(ot + s1->mem_index);
1468
        gen_op_update3_cc(cpu_tmp4);
1469
        set_cc_op(s1, CC_OP_ADCB + ot);
1470
        break;
1471
    case OP_SBBL:
1472
        gen_compute_eflags_c(s1, cpu_tmp4);
1473
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1474
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
1475
        if (d != OR_TMP0)
1476
            gen_op_mov_reg_T0(ot, d);
1477
        else
1478
            gen_op_st_T0_A0(ot + s1->mem_index);
1479
        gen_op_update3_cc(cpu_tmp4);
1480
        set_cc_op(s1, CC_OP_SBBB + ot);
1481
        break;
1482
    case OP_ADDL:
1483
        gen_op_addl_T0_T1();
1484
        if (d != OR_TMP0)
1485
            gen_op_mov_reg_T0(ot, d);
1486
        else
1487
            gen_op_st_T0_A0(ot + s1->mem_index);
1488
        gen_op_update2_cc();
1489
        set_cc_op(s1, CC_OP_ADDB + ot);
1490
        break;
1491
    case OP_SUBL:
1492
        tcg_gen_mov_tl(cpu_cc_srcT, cpu_T[0]);
1493
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1494
        if (d != OR_TMP0)
1495
            gen_op_mov_reg_T0(ot, d);
1496
        else
1497
            gen_op_st_T0_A0(ot + s1->mem_index);
1498
        gen_op_update2_cc();
1499
        set_cc_op(s1, CC_OP_SUBB + ot);
1500
        break;
1501
    default:
1502
    case OP_ANDL:
1503
        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1504
        if (d != OR_TMP0)
1505
            gen_op_mov_reg_T0(ot, d);
1506
        else
1507
            gen_op_st_T0_A0(ot + s1->mem_index);
1508
        gen_op_update1_cc();
1509
        set_cc_op(s1, CC_OP_LOGICB + ot);
1510
        break;
1511
    case OP_ORL:
1512
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1513
        if (d != OR_TMP0)
1514
            gen_op_mov_reg_T0(ot, d);
1515
        else
1516
            gen_op_st_T0_A0(ot + s1->mem_index);
1517
        gen_op_update1_cc();
1518
        set_cc_op(s1, CC_OP_LOGICB + ot);
1519
        break;
1520
    case OP_XORL:
1521
        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1522
        if (d != OR_TMP0)
1523
            gen_op_mov_reg_T0(ot, d);
1524
        else
1525
            gen_op_st_T0_A0(ot + s1->mem_index);
1526
        gen_op_update1_cc();
1527
        set_cc_op(s1, CC_OP_LOGICB + ot);
1528
        break;
1529
    case OP_CMPL:
1530
        tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
1531
        tcg_gen_mov_tl(cpu_cc_srcT, cpu_T[0]);
1532
        tcg_gen_sub_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
1533
        set_cc_op(s1, CC_OP_SUBB + ot);
1534
        break;
1535
    }
1536
}
1537

    
1538
/* if d == OR_TMP0, it means memory operand (address in A0) */
1539
static void gen_inc(DisasContext *s1, int ot, int d, int c)
1540
{
1541
    if (d != OR_TMP0)
1542
        gen_op_mov_TN_reg(ot, 0, d);
1543
    else
1544
        gen_op_ld_T0_A0(ot + s1->mem_index);
1545
    gen_compute_eflags_c(s1, cpu_cc_src);
1546
    if (c > 0) {
1547
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 1);
1548
        set_cc_op(s1, CC_OP_INCB + ot);
1549
    } else {
1550
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], -1);
1551
        set_cc_op(s1, CC_OP_DECB + ot);
1552
    }
1553
    if (d != OR_TMP0)
1554
        gen_op_mov_reg_T0(ot, d);
1555
    else
1556
        gen_op_st_T0_A0(ot + s1->mem_index);
1557
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1558
}
1559

    
1560
static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, 
1561
                            int is_right, int is_arith)
1562
{
1563
    target_ulong mask;
1564
    int shift_label;
1565
    TCGv t0, t1, t2;
1566

    
1567
    if (ot == OT_QUAD) {
1568
        mask = 0x3f;
1569
    } else {
1570
        mask = 0x1f;
1571
    }
1572

    
1573
    /* load */
1574
    if (op1 == OR_TMP0) {
1575
        gen_op_ld_T0_A0(ot + s->mem_index);
1576
    } else {
1577
        gen_op_mov_TN_reg(ot, 0, op1);
1578
    }
1579

    
1580
    t0 = tcg_temp_local_new();
1581
    t1 = tcg_temp_local_new();
1582
    t2 = tcg_temp_local_new();
1583

    
1584
    tcg_gen_andi_tl(t2, cpu_T[1], mask);
1585

    
1586
    if (is_right) {
1587
        if (is_arith) {
1588
            gen_exts(ot, cpu_T[0]);
1589
            tcg_gen_mov_tl(t0, cpu_T[0]);
1590
            tcg_gen_sar_tl(cpu_T[0], cpu_T[0], t2);
1591
        } else {
1592
            gen_extu(ot, cpu_T[0]);
1593
            tcg_gen_mov_tl(t0, cpu_T[0]);
1594
            tcg_gen_shr_tl(cpu_T[0], cpu_T[0], t2);
1595
        }
1596
    } else {
1597
        tcg_gen_mov_tl(t0, cpu_T[0]);
1598
        tcg_gen_shl_tl(cpu_T[0], cpu_T[0], t2);
1599
    }
1600

    
1601
    /* store */
1602
    if (op1 == OR_TMP0) {
1603
        gen_op_st_T0_A0(ot + s->mem_index);
1604
    } else {
1605
        gen_op_mov_reg_T0(ot, op1);
1606
    }
1607

    
1608
    /* Update eflags data because we cannot predict flags afterward.  */
1609
    gen_update_cc_op(s);
1610
    set_cc_op(s, CC_OP_DYNAMIC);
1611

    
1612
    tcg_gen_mov_tl(t1, cpu_T[0]);
1613

    
1614
    shift_label = gen_new_label();
1615
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, shift_label);
1616

    
1617
    tcg_gen_addi_tl(t2, t2, -1);
1618
    tcg_gen_mov_tl(cpu_cc_dst, t1);
1619

    
1620
    if (is_right) {
1621
        if (is_arith) {
1622
            tcg_gen_sar_tl(cpu_cc_src, t0, t2);
1623
        } else {
1624
            tcg_gen_shr_tl(cpu_cc_src, t0, t2);
1625
        }
1626
    } else {
1627
        tcg_gen_shl_tl(cpu_cc_src, t0, t2);
1628
    }
1629

    
1630
    if (is_right) {
1631
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
1632
    } else {
1633
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
1634
    }
1635

    
1636
    gen_set_label(shift_label);
1637

    
1638
    tcg_temp_free(t0);
1639
    tcg_temp_free(t1);
1640
    tcg_temp_free(t2);
1641
}
1642

    
1643
static void gen_shift_rm_im(DisasContext *s, int ot, int op1, int op2,
1644
                            int is_right, int is_arith)
1645
{
1646
    int mask;
1647
    
1648
    if (ot == OT_QUAD)
1649
        mask = 0x3f;
1650
    else
1651
        mask = 0x1f;
1652

    
1653
    /* load */
1654
    if (op1 == OR_TMP0)
1655
        gen_op_ld_T0_A0(ot + s->mem_index);
1656
    else
1657
        gen_op_mov_TN_reg(ot, 0, op1);
1658

    
1659
    op2 &= mask;
1660
    if (op2 != 0) {
1661
        if (is_right) {
1662
            if (is_arith) {
1663
                gen_exts(ot, cpu_T[0]);
1664
                tcg_gen_sari_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1665
                tcg_gen_sari_tl(cpu_T[0], cpu_T[0], op2);
1666
            } else {
1667
                gen_extu(ot, cpu_T[0]);
1668
                tcg_gen_shri_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1669
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], op2);
1670
            }
1671
        } else {
1672
            tcg_gen_shli_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1673
            tcg_gen_shli_tl(cpu_T[0], cpu_T[0], op2);
1674
        }
1675
    }
1676

    
1677
    /* store */
1678
    if (op1 == OR_TMP0)
1679
        gen_op_st_T0_A0(ot + s->mem_index);
1680
    else
1681
        gen_op_mov_reg_T0(ot, op1);
1682
        
1683
    /* update eflags if non zero shift */
1684
    if (op2 != 0) {
1685
        tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
1686
        tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1687
        set_cc_op(s, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1688
    }
1689
}
1690

    
1691
static inline void tcg_gen_lshift(TCGv ret, TCGv arg1, target_long arg2)
1692
{
1693
    if (arg2 >= 0)
1694
        tcg_gen_shli_tl(ret, arg1, arg2);
1695
    else
1696
        tcg_gen_shri_tl(ret, arg1, -arg2);
1697
}
1698

    
1699
static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, 
1700
                          int is_right)
1701
{
1702
    target_ulong mask;
1703
    int label1, label2, data_bits;
1704
    TCGv t0, t1, t2, a0;
1705

    
1706
    /* XXX: inefficient, but we must use local temps */
1707
    t0 = tcg_temp_local_new();
1708
    t1 = tcg_temp_local_new();
1709
    t2 = tcg_temp_local_new();
1710
    a0 = tcg_temp_local_new();
1711

    
1712
    if (ot == OT_QUAD)
1713
        mask = 0x3f;
1714
    else
1715
        mask = 0x1f;
1716

    
1717
    /* load */
1718
    if (op1 == OR_TMP0) {
1719
        tcg_gen_mov_tl(a0, cpu_A0);
1720
        gen_op_ld_v(ot + s->mem_index, t0, a0);
1721
    } else {
1722
        gen_op_mov_v_reg(ot, t0, op1);
1723
    }
1724

    
1725
    tcg_gen_mov_tl(t1, cpu_T[1]);
1726

    
1727
    tcg_gen_andi_tl(t1, t1, mask);
1728

    
1729
    /* Must test zero case to avoid using undefined behaviour in TCG
1730
       shifts. */
1731
    label1 = gen_new_label();
1732
    tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label1);
1733
    
1734
    if (ot <= OT_WORD)
1735
        tcg_gen_andi_tl(cpu_tmp0, t1, (1 << (3 + ot)) - 1);
1736
    else
1737
        tcg_gen_mov_tl(cpu_tmp0, t1);
1738
    
1739
    gen_extu(ot, t0);
1740
    tcg_gen_mov_tl(t2, t0);
1741

    
1742
    data_bits = 8 << ot;
1743
    /* XXX: rely on behaviour of shifts when operand 2 overflows (XXX:
1744
       fix TCG definition) */
1745
    if (is_right) {
1746
        tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp0);
1747
        tcg_gen_subfi_tl(cpu_tmp0, data_bits, cpu_tmp0);
1748
        tcg_gen_shl_tl(t0, t0, cpu_tmp0);
1749
    } else {
1750
        tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp0);
1751
        tcg_gen_subfi_tl(cpu_tmp0, data_bits, cpu_tmp0);
1752
        tcg_gen_shr_tl(t0, t0, cpu_tmp0);
1753
    }
1754
    tcg_gen_or_tl(t0, t0, cpu_tmp4);
1755

    
1756
    gen_set_label(label1);
1757
    /* store */
1758
    if (op1 == OR_TMP0) {
1759
        gen_op_st_v(ot + s->mem_index, t0, a0);
1760
    } else {
1761
        gen_op_mov_reg_v(ot, op1, t0);
1762
    }
1763
    
1764
    /* update eflags.  It is needed anyway most of the time, do it always.  */
1765
    gen_compute_eflags(s);
1766
    assert(s->cc_op == CC_OP_EFLAGS);
1767

    
1768
    label2 = gen_new_label();
1769
    tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label2);
1770

    
1771
    tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
1772
    tcg_gen_xor_tl(cpu_tmp0, t2, t0);
1773
    tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
1774
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
1775
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
1776
    if (is_right) {
1777
        tcg_gen_shri_tl(t0, t0, data_bits - 1);
1778
    }
1779
    tcg_gen_andi_tl(t0, t0, CC_C);
1780
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
1781

    
1782
    gen_set_label(label2);
1783

    
1784
    tcg_temp_free(t0);
1785
    tcg_temp_free(t1);
1786
    tcg_temp_free(t2);
1787
    tcg_temp_free(a0);
1788
}
1789

    
1790
static void gen_rot_rm_im(DisasContext *s, int ot, int op1, int op2,
1791
                          int is_right)
1792
{
1793
    int mask;
1794
    int data_bits;
1795
    TCGv t0, t1, a0;
1796

    
1797
    /* XXX: inefficient, but we must use local temps */
1798
    t0 = tcg_temp_local_new();
1799
    t1 = tcg_temp_local_new();
1800
    a0 = tcg_temp_local_new();
1801

    
1802
    if (ot == OT_QUAD)
1803
        mask = 0x3f;
1804
    else
1805
        mask = 0x1f;
1806

    
1807
    /* load */
1808
    if (op1 == OR_TMP0) {
1809
        tcg_gen_mov_tl(a0, cpu_A0);
1810
        gen_op_ld_v(ot + s->mem_index, t0, a0);
1811
    } else {
1812
        gen_op_mov_v_reg(ot, t0, op1);
1813
    }
1814

    
1815
    gen_extu(ot, t0);
1816
    tcg_gen_mov_tl(t1, t0);
1817

    
1818
    op2 &= mask;
1819
    data_bits = 8 << ot;
1820
    if (op2 != 0) {
1821
        int shift = op2 & ((1 << (3 + ot)) - 1);
1822
        if (is_right) {
1823
            tcg_gen_shri_tl(cpu_tmp4, t0, shift);
1824
            tcg_gen_shli_tl(t0, t0, data_bits - shift);
1825
        }
1826
        else {
1827
            tcg_gen_shli_tl(cpu_tmp4, t0, shift);
1828
            tcg_gen_shri_tl(t0, t0, data_bits - shift);
1829
        }
1830
        tcg_gen_or_tl(t0, t0, cpu_tmp4);
1831
    }
1832

    
1833
    /* store */
1834
    if (op1 == OR_TMP0) {
1835
        gen_op_st_v(ot + s->mem_index, t0, a0);
1836
    } else {
1837
        gen_op_mov_reg_v(ot, op1, t0);
1838
    }
1839

    
1840
    if (op2 != 0) {
1841
        /* update eflags */
1842
        gen_compute_eflags(s);
1843
        assert(s->cc_op == CC_OP_EFLAGS);
1844

    
1845
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
1846
        tcg_gen_xor_tl(cpu_tmp0, t1, t0);
1847
        tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
1848
        tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
1849
        tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
1850
        if (is_right) {
1851
            tcg_gen_shri_tl(t0, t0, data_bits - 1);
1852
        }
1853
        tcg_gen_andi_tl(t0, t0, CC_C);
1854
        tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
1855
    }
1856

    
1857
    tcg_temp_free(t0);
1858
    tcg_temp_free(t1);
1859
    tcg_temp_free(a0);
1860
}
1861

    
1862
/* XXX: add faster immediate = 1 case */
1863
static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, 
1864
                           int is_right)
1865
{
1866
    gen_compute_eflags(s);
1867
    assert(s->cc_op == CC_OP_EFLAGS);
1868

    
1869
    /* load */
1870
    if (op1 == OR_TMP0)
1871
        gen_op_ld_T0_A0(ot + s->mem_index);
1872
    else
1873
        gen_op_mov_TN_reg(ot, 0, op1);
1874
    
1875
    if (is_right) {
1876
        switch (ot) {
1877
        case OT_BYTE:
1878
            gen_helper_rcrb(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1879
            break;
1880
        case OT_WORD:
1881
            gen_helper_rcrw(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1882
            break;
1883
        case OT_LONG:
1884
            gen_helper_rcrl(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1885
            break;
1886
#ifdef TARGET_X86_64
1887
        case OT_QUAD:
1888
            gen_helper_rcrq(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1889
            break;
1890
#endif
1891
        }
1892
    } else {
1893
        switch (ot) {
1894
        case OT_BYTE:
1895
            gen_helper_rclb(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1896
            break;
1897
        case OT_WORD:
1898
            gen_helper_rclw(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1899
            break;
1900
        case OT_LONG:
1901
            gen_helper_rcll(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1902
            break;
1903
#ifdef TARGET_X86_64
1904
        case OT_QUAD:
1905
            gen_helper_rclq(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1906
            break;
1907
#endif
1908
        }
1909
    }
1910
    /* store */
1911
    if (op1 == OR_TMP0)
1912
        gen_op_st_T0_A0(ot + s->mem_index);
1913
    else
1914
        gen_op_mov_reg_T0(ot, op1);
1915
}
1916

    
1917
/* XXX: add faster immediate case */
1918
static void gen_shiftd_rm_T1(DisasContext *s, int ot, int op1,
1919
                             int is_right, TCGv count)
1920
{
1921
    int label1, label2, data_bits;
1922
    target_ulong mask;
1923
    TCGv t0, t1, t2, a0;
1924

    
1925
    t0 = tcg_temp_local_new();
1926
    t1 = tcg_temp_local_new();
1927
    t2 = tcg_temp_local_new();
1928
    a0 = tcg_temp_local_new();
1929

    
1930
    if (ot == OT_QUAD)
1931
        mask = 0x3f;
1932
    else
1933
        mask = 0x1f;
1934

    
1935
    /* load */
1936
    if (op1 == OR_TMP0) {
1937
        tcg_gen_mov_tl(a0, cpu_A0);
1938
        gen_op_ld_v(ot + s->mem_index, t0, a0);
1939
    } else {
1940
        gen_op_mov_v_reg(ot, t0, op1);
1941
    }
1942

    
1943
    tcg_gen_andi_tl(t2, count, mask);
1944
    tcg_gen_mov_tl(t1, cpu_T[1]);
1945

    
1946
    /* Must test zero case to avoid using undefined behaviour in TCG
1947
       shifts. */
1948
    label1 = gen_new_label();
1949
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
1950
    
1951
    tcg_gen_addi_tl(cpu_tmp5, t2, -1);
1952
    if (ot == OT_WORD) {
1953
        /* Note: we implement the Intel behaviour for shift count > 16 */
1954
        if (is_right) {
1955
            tcg_gen_andi_tl(t0, t0, 0xffff);
1956
            tcg_gen_shli_tl(cpu_tmp0, t1, 16);
1957
            tcg_gen_or_tl(t0, t0, cpu_tmp0);
1958
            tcg_gen_ext32u_tl(t0, t0);
1959

    
1960
            tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
1961
            
1962
            /* only needed if count > 16, but a test would complicate */
1963
            tcg_gen_subfi_tl(cpu_tmp5, 32, t2);
1964
            tcg_gen_shl_tl(cpu_tmp0, t0, cpu_tmp5);
1965

    
1966
            tcg_gen_shr_tl(t0, t0, t2);
1967

    
1968
            tcg_gen_or_tl(t0, t0, cpu_tmp0);
1969
        } else {
1970
            /* XXX: not optimal */
1971
            tcg_gen_andi_tl(t0, t0, 0xffff);
1972
            tcg_gen_shli_tl(t1, t1, 16);
1973
            tcg_gen_or_tl(t1, t1, t0);
1974
            tcg_gen_ext32u_tl(t1, t1);
1975
            
1976
            tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
1977
            tcg_gen_subfi_tl(cpu_tmp0, 32, cpu_tmp5);
1978
            tcg_gen_shr_tl(cpu_tmp5, t1, cpu_tmp0);
1979
            tcg_gen_or_tl(cpu_tmp4, cpu_tmp4, cpu_tmp5);
1980

    
1981
            tcg_gen_shl_tl(t0, t0, t2);
1982
            tcg_gen_subfi_tl(cpu_tmp5, 32, t2);
1983
            tcg_gen_shr_tl(t1, t1, cpu_tmp5);
1984
            tcg_gen_or_tl(t0, t0, t1);
1985
        }
1986
    } else {
1987
        data_bits = 8 << ot;
1988
        if (is_right) {
1989
            if (ot == OT_LONG)
1990
                tcg_gen_ext32u_tl(t0, t0);
1991

    
1992
            tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
1993

    
1994
            tcg_gen_shr_tl(t0, t0, t2);
1995
            tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2);
1996
            tcg_gen_shl_tl(t1, t1, cpu_tmp5);
1997
            tcg_gen_or_tl(t0, t0, t1);
1998
            
1999
        } else {
2000
            if (ot == OT_LONG)
2001
                tcg_gen_ext32u_tl(t1, t1);
2002

    
2003
            tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
2004
            
2005
            tcg_gen_shl_tl(t0, t0, t2);
2006
            tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2);
2007
            tcg_gen_shr_tl(t1, t1, cpu_tmp5);
2008
            tcg_gen_or_tl(t0, t0, t1);
2009
        }
2010
    }
2011
    tcg_gen_mov_tl(t1, cpu_tmp4);
2012

    
2013
    gen_set_label(label1);
2014
    /* store */
2015
    if (op1 == OR_TMP0) {
2016
        gen_op_st_v(ot + s->mem_index, t0, a0);
2017
    } else {
2018
        gen_op_mov_reg_v(ot, op1, t0);
2019
    }
2020
    
2021
    /* Update eflags data because we cannot predict flags afterward.  */
2022
    gen_update_cc_op(s);
2023
    set_cc_op(s, CC_OP_DYNAMIC);
2024

    
2025
    label2 = gen_new_label();
2026
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label2);
2027

    
2028
    tcg_gen_mov_tl(cpu_cc_src, t1);
2029
    tcg_gen_mov_tl(cpu_cc_dst, t0);
2030
    if (is_right) {
2031
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
2032
    } else {
2033
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
2034
    }
2035
    gen_set_label(label2);
2036

    
2037
    tcg_temp_free(t0);
2038
    tcg_temp_free(t1);
2039
    tcg_temp_free(t2);
2040
    tcg_temp_free(a0);
2041
}
2042

    
2043
static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
2044
{
2045
    if (s != OR_TMP1)
2046
        gen_op_mov_TN_reg(ot, 1, s);
2047
    switch(op) {
2048
    case OP_ROL:
2049
        gen_rot_rm_T1(s1, ot, d, 0);
2050
        break;
2051
    case OP_ROR:
2052
        gen_rot_rm_T1(s1, ot, d, 1);
2053
        break;
2054
    case OP_SHL:
2055
    case OP_SHL1:
2056
        gen_shift_rm_T1(s1, ot, d, 0, 0);
2057
        break;
2058
    case OP_SHR:
2059
        gen_shift_rm_T1(s1, ot, d, 1, 0);
2060
        break;
2061
    case OP_SAR:
2062
        gen_shift_rm_T1(s1, ot, d, 1, 1);
2063
        break;
2064
    case OP_RCL:
2065
        gen_rotc_rm_T1(s1, ot, d, 0);
2066
        break;
2067
    case OP_RCR:
2068
        gen_rotc_rm_T1(s1, ot, d, 1);
2069
        break;
2070
    }
2071
}
2072

    
2073
static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
2074
{
2075
    switch(op) {
2076
    case OP_ROL:
2077
        gen_rot_rm_im(s1, ot, d, c, 0);
2078
        break;
2079
    case OP_ROR:
2080
        gen_rot_rm_im(s1, ot, d, c, 1);
2081
        break;
2082
    case OP_SHL:
2083
    case OP_SHL1:
2084
        gen_shift_rm_im(s1, ot, d, c, 0, 0);
2085
        break;
2086
    case OP_SHR:
2087
        gen_shift_rm_im(s1, ot, d, c, 1, 0);
2088
        break;
2089
    case OP_SAR:
2090
        gen_shift_rm_im(s1, ot, d, c, 1, 1);
2091
        break;
2092
    default:
2093
        /* currently not optimized */
2094
        gen_op_movl_T1_im(c);
2095
        gen_shift(s1, op, ot, d, OR_TMP1);
2096
        break;
2097
    }
2098
}
2099

    
2100
static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm,
2101
                          int *reg_ptr, int *offset_ptr)
2102
{
2103
    target_long disp;
2104
    int havesib;
2105
    int base;
2106
    int index;
2107
    int scale;
2108
    int opreg;
2109
    int mod, rm, code, override, must_add_seg;
2110

    
2111
    override = s->override;
2112
    must_add_seg = s->addseg;
2113
    if (override >= 0)
2114
        must_add_seg = 1;
2115
    mod = (modrm >> 6) & 3;
2116
    rm = modrm & 7;
2117

    
2118
    if (s->aflag) {
2119

    
2120
        havesib = 0;
2121
        base = rm;
2122
        index = 0;
2123
        scale = 0;
2124

    
2125
        if (base == 4) {
2126
            havesib = 1;
2127
            code = cpu_ldub_code(env, s->pc++);
2128
            scale = (code >> 6) & 3;
2129
            index = ((code >> 3) & 7) | REX_X(s);
2130
            base = (code & 7);
2131
        }
2132
        base |= REX_B(s);
2133

    
2134
        switch (mod) {
2135
        case 0:
2136
            if ((base & 7) == 5) {
2137
                base = -1;
2138
                disp = (int32_t)cpu_ldl_code(env, s->pc);
2139
                s->pc += 4;
2140
                if (CODE64(s) && !havesib) {
2141
                    disp += s->pc + s->rip_offset;
2142
                }
2143
            } else {
2144
                disp = 0;
2145
            }
2146
            break;
2147
        case 1:
2148
            disp = (int8_t)cpu_ldub_code(env, s->pc++);
2149
            break;
2150
        default:
2151
        case 2:
2152
            disp = (int32_t)cpu_ldl_code(env, s->pc);
2153
            s->pc += 4;
2154
            break;
2155
        }
2156

    
2157
        if (base >= 0) {
2158
            /* for correct popl handling with esp */
2159
            if (base == 4 && s->popl_esp_hack)
2160
                disp += s->popl_esp_hack;
2161
#ifdef TARGET_X86_64
2162
            if (s->aflag == 2) {
2163
                gen_op_movq_A0_reg(base);
2164
                if (disp != 0) {
2165
                    gen_op_addq_A0_im(disp);
2166
                }
2167
            } else
2168
#endif
2169
            {
2170
                gen_op_movl_A0_reg(base);
2171
                if (disp != 0)
2172
                    gen_op_addl_A0_im(disp);
2173
            }
2174
        } else {
2175
#ifdef TARGET_X86_64
2176
            if (s->aflag == 2) {
2177
                gen_op_movq_A0_im(disp);
2178
            } else
2179
#endif
2180
            {
2181
                gen_op_movl_A0_im(disp);
2182
            }
2183
        }
2184
        /* index == 4 means no index */
2185
        if (havesib && (index != 4)) {
2186
#ifdef TARGET_X86_64
2187
            if (s->aflag == 2) {
2188
                gen_op_addq_A0_reg_sN(scale, index);
2189
            } else
2190
#endif
2191
            {
2192
                gen_op_addl_A0_reg_sN(scale, index);
2193
            }
2194
        }
2195
        if (must_add_seg) {
2196
            if (override < 0) {
2197
                if (base == R_EBP || base == R_ESP)
2198
                    override = R_SS;
2199
                else
2200
                    override = R_DS;
2201
            }
2202
#ifdef TARGET_X86_64
2203
            if (s->aflag == 2) {
2204
                gen_op_addq_A0_seg(override);
2205
            } else
2206
#endif
2207
            {
2208
                gen_op_addl_A0_seg(s, override);
2209
            }
2210
        }
2211
    } else {
2212
        switch (mod) {
2213
        case 0:
2214
            if (rm == 6) {
2215
                disp = cpu_lduw_code(env, s->pc);
2216
                s->pc += 2;
2217
                gen_op_movl_A0_im(disp);
2218
                rm = 0; /* avoid SS override */
2219
                goto no_rm;
2220
            } else {
2221
                disp = 0;
2222
            }
2223
            break;
2224
        case 1:
2225
            disp = (int8_t)cpu_ldub_code(env, s->pc++);
2226
            break;
2227
        default:
2228
        case 2:
2229
            disp = cpu_lduw_code(env, s->pc);
2230
            s->pc += 2;
2231
            break;
2232
        }
2233
        switch(rm) {
2234
        case 0:
2235
            gen_op_movl_A0_reg(R_EBX);
2236
            gen_op_addl_A0_reg_sN(0, R_ESI);
2237
            break;
2238
        case 1:
2239
            gen_op_movl_A0_reg(R_EBX);
2240
            gen_op_addl_A0_reg_sN(0, R_EDI);
2241
            break;
2242
        case 2:
2243
            gen_op_movl_A0_reg(R_EBP);
2244
            gen_op_addl_A0_reg_sN(0, R_ESI);
2245
            break;
2246
        case 3:
2247
            gen_op_movl_A0_reg(R_EBP);
2248
            gen_op_addl_A0_reg_sN(0, R_EDI);
2249
            break;
2250
        case 4:
2251
            gen_op_movl_A0_reg(R_ESI);
2252
            break;
2253
        case 5:
2254
            gen_op_movl_A0_reg(R_EDI);
2255
            break;
2256
        case 6:
2257
            gen_op_movl_A0_reg(R_EBP);
2258
            break;
2259
        default:
2260
        case 7:
2261
            gen_op_movl_A0_reg(R_EBX);
2262
            break;
2263
        }
2264
        if (disp != 0)
2265
            gen_op_addl_A0_im(disp);
2266
        gen_op_andl_A0_ffff();
2267
    no_rm:
2268
        if (must_add_seg) {
2269
            if (override < 0) {
2270
                if (rm == 2 || rm == 3 || rm == 6)
2271
                    override = R_SS;
2272
                else
2273
                    override = R_DS;
2274
            }
2275
            gen_op_addl_A0_seg(s, override);
2276
        }
2277
    }
2278

    
2279
    opreg = OR_A0;
2280
    disp = 0;
2281
    *reg_ptr = opreg;
2282
    *offset_ptr = disp;
2283
}
2284

    
2285
static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
2286
{
2287
    int mod, rm, base, code;
2288

    
2289
    mod = (modrm >> 6) & 3;
2290
    if (mod == 3)
2291
        return;
2292
    rm = modrm & 7;
2293

    
2294
    if (s->aflag) {
2295

    
2296
        base = rm;
2297

    
2298
        if (base == 4) {
2299
            code = cpu_ldub_code(env, s->pc++);
2300
            base = (code & 7);
2301
        }
2302

    
2303
        switch (mod) {
2304
        case 0:
2305
            if (base == 5) {
2306
                s->pc += 4;
2307
            }
2308
            break;
2309
        case 1:
2310
            s->pc++;
2311
            break;
2312
        default:
2313
        case 2:
2314
            s->pc += 4;
2315
            break;
2316
        }
2317
    } else {
2318
        switch (mod) {
2319
        case 0:
2320
            if (rm == 6) {
2321
                s->pc += 2;
2322
            }
2323
            break;
2324
        case 1:
2325
            s->pc++;
2326
            break;
2327
        default:
2328
        case 2:
2329
            s->pc += 2;
2330
            break;
2331
        }
2332
    }
2333
}
2334

    
2335
/* used for LEA and MOV AX, mem */
2336
static void gen_add_A0_ds_seg(DisasContext *s)
2337
{
2338
    int override, must_add_seg;
2339
    must_add_seg = s->addseg;
2340
    override = R_DS;
2341
    if (s->override >= 0) {
2342
        override = s->override;
2343
        must_add_seg = 1;
2344
    }
2345
    if (must_add_seg) {
2346
#ifdef TARGET_X86_64
2347
        if (CODE64(s)) {
2348
            gen_op_addq_A0_seg(override);
2349
        } else
2350
#endif
2351
        {
2352
            gen_op_addl_A0_seg(s, override);
2353
        }
2354
    }
2355
}
2356

    
2357
/* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2358
   OR_TMP0 */
2359
static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm,
2360
                           int ot, int reg, int is_store)
2361
{
2362
    int mod, rm, opreg, disp;
2363

    
2364
    mod = (modrm >> 6) & 3;
2365
    rm = (modrm & 7) | REX_B(s);
2366
    if (mod == 3) {
2367
        if (is_store) {
2368
            if (reg != OR_TMP0)
2369
                gen_op_mov_TN_reg(ot, 0, reg);
2370
            gen_op_mov_reg_T0(ot, rm);
2371
        } else {
2372
            gen_op_mov_TN_reg(ot, 0, rm);
2373
            if (reg != OR_TMP0)
2374
                gen_op_mov_reg_T0(ot, reg);
2375
        }
2376
    } else {
2377
        gen_lea_modrm(env, s, modrm, &opreg, &disp);
2378
        if (is_store) {
2379
            if (reg != OR_TMP0)
2380
                gen_op_mov_TN_reg(ot, 0, reg);
2381
            gen_op_st_T0_A0(ot + s->mem_index);
2382
        } else {
2383
            gen_op_ld_T0_A0(ot + s->mem_index);
2384
            if (reg != OR_TMP0)
2385
                gen_op_mov_reg_T0(ot, reg);
2386
        }
2387
    }
2388
}
2389

    
2390
static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, int ot)
2391
{
2392
    uint32_t ret;
2393

    
2394
    switch(ot) {
2395
    case OT_BYTE:
2396
        ret = cpu_ldub_code(env, s->pc);
2397
        s->pc++;
2398
        break;
2399
    case OT_WORD:
2400
        ret = cpu_lduw_code(env, s->pc);
2401
        s->pc += 2;
2402
        break;
2403
    default:
2404
    case OT_LONG:
2405
        ret = cpu_ldl_code(env, s->pc);
2406
        s->pc += 4;
2407
        break;
2408
    }
2409
    return ret;
2410
}
2411

    
2412
static inline int insn_const_size(unsigned int ot)
2413
{
2414
    if (ot <= OT_LONG)
2415
        return 1 << ot;
2416
    else
2417
        return 4;
2418
}
2419

    
2420
static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
2421
{
2422
    TranslationBlock *tb;
2423
    target_ulong pc;
2424

    
2425
    pc = s->cs_base + eip;
2426
    tb = s->tb;
2427
    /* NOTE: we handle the case where the TB spans two pages here */
2428
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
2429
        (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
2430
        /* jump to same page: we can use a direct jump */
2431
        tcg_gen_goto_tb(tb_num);
2432
        gen_jmp_im(eip);
2433
        tcg_gen_exit_tb((tcg_target_long)tb + tb_num);
2434
    } else {
2435
        /* jump to another page: currently not optimized */
2436
        gen_jmp_im(eip);
2437
        gen_eob(s);
2438
    }
2439
}
2440

    
2441
static inline void gen_jcc(DisasContext *s, int b,
2442
                           target_ulong val, target_ulong next_eip)
2443
{
2444
    int l1, l2;
2445

    
2446
    if (s->jmp_opt) {
2447
        l1 = gen_new_label();
2448
        gen_jcc1(s, b, l1);
2449

    
2450
        gen_goto_tb(s, 0, next_eip);
2451

    
2452
        gen_set_label(l1);
2453
        gen_goto_tb(s, 1, val);
2454
        s->is_jmp = DISAS_TB_JUMP;
2455
    } else {
2456
        l1 = gen_new_label();
2457
        l2 = gen_new_label();
2458
        gen_jcc1(s, b, l1);
2459

    
2460
        gen_jmp_im(next_eip);
2461
        tcg_gen_br(l2);
2462

    
2463
        gen_set_label(l1);
2464
        gen_jmp_im(val);
2465
        gen_set_label(l2);
2466
        gen_eob(s);
2467
    }
2468
}
2469

    
2470
static void gen_cmovcc1(CPUX86State *env, DisasContext *s, int ot, int b,
2471
                        int modrm, int reg)
2472
{
2473
    CCPrepare cc;
2474

    
2475
    gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
2476

    
2477
    cc = gen_prepare_cc(s, b, cpu_T[1]);
2478
    if (cc.mask != -1) {
2479
        TCGv t0 = tcg_temp_new();
2480
        tcg_gen_andi_tl(t0, cc.reg, cc.mask);
2481
        cc.reg = t0;
2482
    }
2483
    if (!cc.use_reg2) {
2484
        cc.reg2 = tcg_const_tl(cc.imm);
2485
    }
2486

    
2487
    tcg_gen_movcond_tl(cc.cond, cpu_T[0], cc.reg, cc.reg2,
2488
                       cpu_T[0], cpu_regs[reg]);
2489
    gen_op_mov_reg_T0(ot, reg);
2490

    
2491
    if (cc.mask != -1) {
2492
        tcg_temp_free(cc.reg);
2493
    }
2494
    if (!cc.use_reg2) {
2495
        tcg_temp_free(cc.reg2);
2496
    }
2497
}
2498

    
2499
static inline void gen_op_movl_T0_seg(int seg_reg)
2500
{
2501
    tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
2502
                     offsetof(CPUX86State,segs[seg_reg].selector));
2503
}
2504

    
2505
static inline void gen_op_movl_seg_T0_vm(int seg_reg)
2506
{
2507
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
2508
    tcg_gen_st32_tl(cpu_T[0], cpu_env, 
2509
                    offsetof(CPUX86State,segs[seg_reg].selector));
2510
    tcg_gen_shli_tl(cpu_T[0], cpu_T[0], 4);
2511
    tcg_gen_st_tl(cpu_T[0], cpu_env, 
2512
                  offsetof(CPUX86State,segs[seg_reg].base));
2513
}
2514

    
2515
/* move T0 to seg_reg and compute if the CPU state may change. Never
2516
   call this function with seg_reg == R_CS */
2517
static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
2518
{
2519
    if (s->pe && !s->vm86) {
2520
        /* XXX: optimize by finding processor state dynamically */
2521
        gen_update_cc_op(s);
2522
        gen_jmp_im(cur_eip);
2523
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
2524
        gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), cpu_tmp2_i32);
2525
        /* abort translation because the addseg value may change or
2526
           because ss32 may change. For R_SS, translation must always
2527
           stop as a special handling must be done to disable hardware
2528
           interrupts for the next instruction */
2529
        if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
2530
            s->is_jmp = DISAS_TB_JUMP;
2531
    } else {
2532
        gen_op_movl_seg_T0_vm(seg_reg);
2533
        if (seg_reg == R_SS)
2534
            s->is_jmp = DISAS_TB_JUMP;
2535
    }
2536
}
2537

    
2538
static inline int svm_is_rep(int prefixes)
2539
{
2540
    return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
2541
}
2542

    
2543
static inline void
2544
gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2545
                              uint32_t type, uint64_t param)
2546
{
2547
    /* no SVM activated; fast case */
2548
    if (likely(!(s->flags & HF_SVMI_MASK)))
2549
        return;
2550
    gen_update_cc_op(s);
2551
    gen_jmp_im(pc_start - s->cs_base);
2552
    gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type),
2553
                                         tcg_const_i64(param));
2554
}
2555

    
2556
static inline void
2557
gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
2558
{
2559
    gen_svm_check_intercept_param(s, pc_start, type, 0);
2560
}
2561

    
2562
static inline void gen_stack_update(DisasContext *s, int addend)
2563
{
2564
#ifdef TARGET_X86_64
2565
    if (CODE64(s)) {
2566
        gen_op_add_reg_im(2, R_ESP, addend);
2567
    } else
2568
#endif
2569
    if (s->ss32) {
2570
        gen_op_add_reg_im(1, R_ESP, addend);
2571
    } else {
2572
        gen_op_add_reg_im(0, R_ESP, addend);
2573
    }
2574
}
2575

    
2576
/* generate a push. It depends on ss32, addseg and dflag */
2577
static void gen_push_T0(DisasContext *s)
2578
{
2579
#ifdef TARGET_X86_64
2580
    if (CODE64(s)) {
2581
        gen_op_movq_A0_reg(R_ESP);
2582
        if (s->dflag) {
2583
            gen_op_addq_A0_im(-8);
2584
            gen_op_st_T0_A0(OT_QUAD + s->mem_index);
2585
        } else {
2586
            gen_op_addq_A0_im(-2);
2587
            gen_op_st_T0_A0(OT_WORD + s->mem_index);
2588
        }
2589
        gen_op_mov_reg_A0(2, R_ESP);
2590
    } else
2591
#endif
2592
    {
2593
        gen_op_movl_A0_reg(R_ESP);
2594
        if (!s->dflag)
2595
            gen_op_addl_A0_im(-2);
2596
        else
2597
            gen_op_addl_A0_im(-4);
2598
        if (s->ss32) {
2599
            if (s->addseg) {
2600
                tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2601
                gen_op_addl_A0_seg(s, R_SS);
2602
            }
2603
        } else {
2604
            gen_op_andl_A0_ffff();
2605
            tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2606
            gen_op_addl_A0_seg(s, R_SS);
2607
        }
2608
        gen_op_st_T0_A0(s->dflag + 1 + s->mem_index);
2609
        if (s->ss32 && !s->addseg)
2610
            gen_op_mov_reg_A0(1, R_ESP);
2611
        else
2612
            gen_op_mov_reg_T1(s->ss32 + 1, R_ESP);
2613
    }
2614
}
2615

    
2616
/* generate a push. It depends on ss32, addseg and dflag */
2617
/* slower version for T1, only used for call Ev */
2618
static void gen_push_T1(DisasContext *s)
2619
{
2620
#ifdef TARGET_X86_64
2621
    if (CODE64(s)) {
2622
        gen_op_movq_A0_reg(R_ESP);
2623
        if (s->dflag) {
2624
            gen_op_addq_A0_im(-8);
2625
            gen_op_st_T1_A0(OT_QUAD + s->mem_index);
2626
        } else {
2627
            gen_op_addq_A0_im(-2);
2628
            gen_op_st_T0_A0(OT_WORD + s->mem_index);
2629
        }
2630
        gen_op_mov_reg_A0(2, R_ESP);
2631
    } else
2632
#endif
2633
    {
2634
        gen_op_movl_A0_reg(R_ESP);
2635
        if (!s->dflag)
2636
            gen_op_addl_A0_im(-2);
2637
        else
2638
            gen_op_addl_A0_im(-4);
2639
        if (s->ss32) {
2640
            if (s->addseg) {
2641
                gen_op_addl_A0_seg(s, R_SS);
2642
            }
2643
        } else {
2644
            gen_op_andl_A0_ffff();
2645
            gen_op_addl_A0_seg(s, R_SS);
2646
        }
2647
        gen_op_st_T1_A0(s->dflag + 1 + s->mem_index);
2648

    
2649
        if (s->ss32 && !s->addseg)
2650
            gen_op_mov_reg_A0(1, R_ESP);
2651
        else
2652
            gen_stack_update(s, (-2) << s->dflag);
2653
    }
2654
}
2655

    
2656
/* two step pop is necessary for precise exceptions */
2657
static void gen_pop_T0(DisasContext *s)
2658
{
2659
#ifdef TARGET_X86_64
2660
    if (CODE64(s)) {
2661
        gen_op_movq_A0_reg(R_ESP);
2662
        gen_op_ld_T0_A0((s->dflag ? OT_QUAD : OT_WORD) + s->mem_index);
2663
    } else
2664
#endif
2665
    {
2666
        gen_op_movl_A0_reg(R_ESP);
2667
        if (s->ss32) {
2668
            if (s->addseg)
2669
                gen_op_addl_A0_seg(s, R_SS);
2670
        } else {
2671
            gen_op_andl_A0_ffff();
2672
            gen_op_addl_A0_seg(s, R_SS);
2673
        }
2674
        gen_op_ld_T0_A0(s->dflag + 1 + s->mem_index);
2675
    }
2676
}
2677

    
2678
static void gen_pop_update(DisasContext *s)
2679
{
2680
#ifdef TARGET_X86_64
2681
    if (CODE64(s) && s->dflag) {
2682
        gen_stack_update(s, 8);
2683
    } else
2684
#endif
2685
    {
2686
        gen_stack_update(s, 2 << s->dflag);
2687
    }
2688
}
2689

    
2690
static void gen_stack_A0(DisasContext *s)
2691
{
2692
    gen_op_movl_A0_reg(R_ESP);
2693
    if (!s->ss32)
2694
        gen_op_andl_A0_ffff();
2695
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2696
    if (s->addseg)
2697
        gen_op_addl_A0_seg(s, R_SS);
2698
}
2699

    
2700
/* NOTE: wrap around in 16 bit not fully handled */
2701
static void gen_pusha(DisasContext *s)
2702
{
2703
    int i;
2704
    gen_op_movl_A0_reg(R_ESP);
2705
    gen_op_addl_A0_im(-16 <<  s->dflag);
2706
    if (!s->ss32)
2707
        gen_op_andl_A0_ffff();
2708
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2709
    if (s->addseg)
2710
        gen_op_addl_A0_seg(s, R_SS);
2711
    for(i = 0;i < 8; i++) {
2712
        gen_op_mov_TN_reg(OT_LONG, 0, 7 - i);
2713
        gen_op_st_T0_A0(OT_WORD + s->dflag + s->mem_index);
2714
        gen_op_addl_A0_im(2 <<  s->dflag);
2715
    }
2716
    gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2717
}
2718

    
2719
/* NOTE: wrap around in 16 bit not fully handled */
2720
static void gen_popa(DisasContext *s)
2721
{
2722
    int i;
2723
    gen_op_movl_A0_reg(R_ESP);
2724
    if (!s->ss32)
2725
        gen_op_andl_A0_ffff();
2726
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2727
    tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 16 <<  s->dflag);
2728
    if (s->addseg)
2729
        gen_op_addl_A0_seg(s, R_SS);
2730
    for(i = 0;i < 8; i++) {
2731
        /* ESP is not reloaded */
2732
        if (i != 3) {
2733
            gen_op_ld_T0_A0(OT_WORD + s->dflag + s->mem_index);
2734
            gen_op_mov_reg_T0(OT_WORD + s->dflag, 7 - i);
2735
        }
2736
        gen_op_addl_A0_im(2 <<  s->dflag);
2737
    }
2738
    gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2739
}
2740

    
2741
static void gen_enter(DisasContext *s, int esp_addend, int level)
2742
{
2743
    int ot, opsize;
2744

    
2745
    level &= 0x1f;
2746
#ifdef TARGET_X86_64
2747
    if (CODE64(s)) {
2748
        ot = s->dflag ? OT_QUAD : OT_WORD;
2749
        opsize = 1 << ot;
2750

    
2751
        gen_op_movl_A0_reg(R_ESP);
2752
        gen_op_addq_A0_im(-opsize);
2753
        tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2754

    
2755
        /* push bp */
2756
        gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
2757
        gen_op_st_T0_A0(ot + s->mem_index);
2758
        if (level) {
2759
            /* XXX: must save state */
2760
            gen_helper_enter64_level(cpu_env, tcg_const_i32(level),
2761
                                     tcg_const_i32((ot == OT_QUAD)),
2762
                                     cpu_T[1]);
2763
        }
2764
        gen_op_mov_reg_T1(ot, R_EBP);
2765
        tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2766
        gen_op_mov_reg_T1(OT_QUAD, R_ESP);
2767
    } else
2768
#endif
2769
    {
2770
        ot = s->dflag + OT_WORD;
2771
        opsize = 2 << s->dflag;
2772

    
2773
        gen_op_movl_A0_reg(R_ESP);
2774
        gen_op_addl_A0_im(-opsize);
2775
        if (!s->ss32)
2776
            gen_op_andl_A0_ffff();
2777
        tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2778
        if (s->addseg)
2779
            gen_op_addl_A0_seg(s, R_SS);
2780
        /* push bp */
2781
        gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
2782
        gen_op_st_T0_A0(ot + s->mem_index);
2783
        if (level) {
2784
            /* XXX: must save state */
2785
            gen_helper_enter_level(cpu_env, tcg_const_i32(level),
2786
                                   tcg_const_i32(s->dflag),
2787
                                   cpu_T[1]);
2788
        }
2789
        gen_op_mov_reg_T1(ot, R_EBP);
2790
        tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2791
        gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2792
    }
2793
}
2794

    
2795
static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2796
{
2797
    gen_update_cc_op(s);
2798
    gen_jmp_im(cur_eip);
2799
    gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
2800
    s->is_jmp = DISAS_TB_JUMP;
2801
}
2802

    
2803
/* an interrupt is different from an exception because of the
2804
   privilege checks */
2805
static void gen_interrupt(DisasContext *s, int intno,
2806
                          target_ulong cur_eip, target_ulong next_eip)
2807
{
2808
    gen_update_cc_op(s);
2809
    gen_jmp_im(cur_eip);
2810
    gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
2811
                               tcg_const_i32(next_eip - cur_eip));
2812
    s->is_jmp = DISAS_TB_JUMP;
2813
}
2814

    
2815
static void gen_debug(DisasContext *s, target_ulong cur_eip)
2816
{
2817
    gen_update_cc_op(s);
2818
    gen_jmp_im(cur_eip);
2819
    gen_helper_debug(cpu_env);
2820
    s->is_jmp = DISAS_TB_JUMP;
2821
}
2822

    
2823
/* generate a generic end of block. Trace exception is also generated
2824
   if needed */
2825
static void gen_eob(DisasContext *s)
2826
{
2827
    gen_update_cc_op(s);
2828
    if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
2829
        gen_helper_reset_inhibit_irq(cpu_env);
2830
    }
2831
    if (s->tb->flags & HF_RF_MASK) {
2832
        gen_helper_reset_rf(cpu_env);
2833
    }
2834
    if (s->singlestep_enabled) {
2835
        gen_helper_debug(cpu_env);
2836
    } else if (s->tf) {
2837
        gen_helper_single_step(cpu_env);
2838
    } else {
2839
        tcg_gen_exit_tb(0);
2840
    }
2841
    s->is_jmp = DISAS_TB_JUMP;
2842
}
2843

    
2844
/* generate a jump to eip. No segment change must happen before as a
2845
   direct call to the next block may occur */
2846
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2847
{
2848
    gen_update_cc_op(s);
2849
    set_cc_op(s, CC_OP_DYNAMIC);
2850
    if (s->jmp_opt) {
2851
        gen_goto_tb(s, tb_num, eip);
2852
        s->is_jmp = DISAS_TB_JUMP;
2853
    } else {
2854
        gen_jmp_im(eip);
2855
        gen_eob(s);
2856
    }
2857
}
2858

    
2859
static void gen_jmp(DisasContext *s, target_ulong eip)
2860
{
2861
    gen_jmp_tb(s, eip, 0);
2862
}
2863

    
2864
static inline void gen_ldq_env_A0(int idx, int offset)
2865
{
2866
    int mem_index = (idx >> 2) - 1;
2867
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2868
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
2869
}
2870

    
2871
static inline void gen_stq_env_A0(int idx, int offset)
2872
{
2873
    int mem_index = (idx >> 2) - 1;
2874
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
2875
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2876
}
2877

    
2878
static inline void gen_ldo_env_A0(int idx, int offset)
2879
{
2880
    int mem_index = (idx >> 2) - 1;
2881
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2882
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2883
    tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2884
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2885
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2886
}
2887

    
2888
static inline void gen_sto_env_A0(int idx, int offset)
2889
{
2890
    int mem_index = (idx >> 2) - 1;
2891
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2892
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2893
    tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2894
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2895
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2896
}
2897

    
2898
static inline void gen_op_movo(int d_offset, int s_offset)
2899
{
2900
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2901
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2902
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + 8);
2903
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + 8);
2904
}
2905

    
2906
static inline void gen_op_movq(int d_offset, int s_offset)
2907
{
2908
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2909
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2910
}
2911

    
2912
static inline void gen_op_movl(int d_offset, int s_offset)
2913
{
2914
    tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
2915
    tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
2916
}
2917

    
2918
static inline void gen_op_movq_env_0(int d_offset)
2919
{
2920
    tcg_gen_movi_i64(cpu_tmp1_i64, 0);
2921
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2922
}
2923

    
2924
typedef void (*SSEFunc_i_ep)(TCGv_i32 val, TCGv_ptr env, TCGv_ptr reg);
2925
typedef void (*SSEFunc_l_ep)(TCGv_i64 val, TCGv_ptr env, TCGv_ptr reg);
2926
typedef void (*SSEFunc_0_epi)(TCGv_ptr env, TCGv_ptr reg, TCGv_i32 val);
2927
typedef void (*SSEFunc_0_epl)(TCGv_ptr env, TCGv_ptr reg, TCGv_i64 val);
2928
typedef void (*SSEFunc_0_epp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b);
2929
typedef void (*SSEFunc_0_eppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2930
                               TCGv_i32 val);
2931
typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val);
2932
typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2933
                               TCGv val);
2934

    
2935
#define SSE_SPECIAL ((void *)1)
2936
#define SSE_DUMMY ((void *)2)
2937

    
2938
#define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2939
#define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2940
                     gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2941

    
2942
static const SSEFunc_0_epp sse_op_table1[256][4] = {
2943
    /* 3DNow! extensions */
2944
    [0x0e] = { SSE_DUMMY }, /* femms */
2945
    [0x0f] = { SSE_DUMMY }, /* pf... */
2946
    /* pure SSE operations */
2947
    [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2948
    [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2949
    [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2950
    [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
2951
    [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
2952
    [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
2953
    [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */
2954
    [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */
2955

    
2956
    [0x28] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2957
    [0x29] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2958
    [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2959
    [0x2b] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd, movntss, movntsd */
2960
    [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2961
    [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2962
    [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd },
2963
    [0x2f] = { gen_helper_comiss, gen_helper_comisd },
2964
    [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2965
    [0x51] = SSE_FOP(sqrt),
2966
    [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL },
2967
    [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL },
2968
    [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */
2969
    [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */
2970
    [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */
2971
    [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */
2972
    [0x58] = SSE_FOP(add),
2973
    [0x59] = SSE_FOP(mul),
2974
    [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps,
2975
               gen_helper_cvtss2sd, gen_helper_cvtsd2ss },
2976
    [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq },
2977
    [0x5c] = SSE_FOP(sub),
2978
    [0x5d] = SSE_FOP(min),
2979
    [0x5e] = SSE_FOP(div),
2980
    [0x5f] = SSE_FOP(max),
2981

    
2982
    [0xc2] = SSE_FOP(cmpeq),
2983
    [0xc6] = { (SSEFunc_0_epp)gen_helper_shufps,
2984
               (SSEFunc_0_epp)gen_helper_shufpd }, /* XXX: casts */
2985

    
2986
    /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX.  */
2987
    [0x38] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2988
    [0x3a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2989

    
2990
    /* MMX ops and their SSE extensions */
2991
    [0x60] = MMX_OP2(punpcklbw),
2992
    [0x61] = MMX_OP2(punpcklwd),
2993
    [0x62] = MMX_OP2(punpckldq),
2994
    [0x63] = MMX_OP2(packsswb),
2995
    [0x64] = MMX_OP2(pcmpgtb),
2996
    [0x65] = MMX_OP2(pcmpgtw),
2997
    [0x66] = MMX_OP2(pcmpgtl),
2998
    [0x67] = MMX_OP2(packuswb),
2999
    [0x68] = MMX_OP2(punpckhbw),
3000
    [0x69] = MMX_OP2(punpckhwd),
3001
    [0x6a] = MMX_OP2(punpckhdq),
3002
    [0x6b] = MMX_OP2(packssdw),
3003
    [0x6c] = { NULL, gen_helper_punpcklqdq_xmm },
3004
    [0x6d] = { NULL, gen_helper_punpckhqdq_xmm },
3005
    [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
3006
    [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
3007
    [0x70] = { (SSEFunc_0_epp)gen_helper_pshufw_mmx,
3008
               (SSEFunc_0_epp)gen_helper_pshufd_xmm,
3009
               (SSEFunc_0_epp)gen_helper_pshufhw_xmm,
3010
               (SSEFunc_0_epp)gen_helper_pshuflw_xmm }, /* XXX: casts */
3011
    [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
3012
    [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
3013
    [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
3014
    [0x74] = MMX_OP2(pcmpeqb),
3015
    [0x75] = MMX_OP2(pcmpeqw),
3016
    [0x76] = MMX_OP2(pcmpeql),
3017
    [0x77] = { SSE_DUMMY }, /* emms */
3018
    [0x78] = { NULL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* extrq_i, insertq_i */
3019
    [0x79] = { NULL, gen_helper_extrq_r, NULL, gen_helper_insertq_r },
3020
    [0x7c] = { NULL, gen_helper_haddpd, NULL, gen_helper_haddps },
3021
    [0x7d] = { NULL, gen_helper_hsubpd, NULL, gen_helper_hsubps },
3022
    [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
3023
    [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
3024
    [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
3025
    [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
3026
    [0xd0] = { NULL, gen_helper_addsubpd, NULL, gen_helper_addsubps },
3027
    [0xd1] = MMX_OP2(psrlw),
3028
    [0xd2] = MMX_OP2(psrld),
3029
    [0xd3] = MMX_OP2(psrlq),
3030
    [0xd4] = MMX_OP2(paddq),
3031
    [0xd5] = MMX_OP2(pmullw),
3032
    [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
3033
    [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
3034
    [0xd8] = MMX_OP2(psubusb),
3035
    [0xd9] = MMX_OP2(psubusw),
3036
    [0xda] = MMX_OP2(pminub),
3037
    [0xdb] = MMX_OP2(pand),
3038
    [0xdc] = MMX_OP2(paddusb),
3039
    [0xdd] = MMX_OP2(paddusw),
3040
    [0xde] = MMX_OP2(pmaxub),
3041
    [0xdf] = MMX_OP2(pandn),
3042
    [0xe0] = MMX_OP2(pavgb),
3043
    [0xe1] = MMX_OP2(psraw),
3044
    [0xe2] = MMX_OP2(psrad),
3045
    [0xe3] = MMX_OP2(pavgw),
3046
    [0xe4] = MMX_OP2(pmulhuw),
3047
    [0xe5] = MMX_OP2(pmulhw),
3048
    [0xe6] = { NULL, gen_helper_cvttpd2dq, gen_helper_cvtdq2pd, gen_helper_cvtpd2dq },
3049
    [0xe7] = { SSE_SPECIAL , SSE_SPECIAL },  /* movntq, movntq */
3050
    [0xe8] = MMX_OP2(psubsb),
3051
    [0xe9] = MMX_OP2(psubsw),
3052
    [0xea] = MMX_OP2(pminsw),
3053
    [0xeb] = MMX_OP2(por),
3054
    [0xec] = MMX_OP2(paddsb),
3055
    [0xed] = MMX_OP2(paddsw),
3056
    [0xee] = MMX_OP2(pmaxsw),
3057
    [0xef] = MMX_OP2(pxor),
3058
    [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
3059
    [0xf1] = MMX_OP2(psllw),
3060
    [0xf2] = MMX_OP2(pslld),
3061
    [0xf3] = MMX_OP2(psllq),
3062
    [0xf4] = MMX_OP2(pmuludq),
3063
    [0xf5] = MMX_OP2(pmaddwd),
3064
    [0xf6] = MMX_OP2(psadbw),
3065
    [0xf7] = { (SSEFunc_0_epp)gen_helper_maskmov_mmx,
3066
               (SSEFunc_0_epp)gen_helper_maskmov_xmm }, /* XXX: casts */
3067
    [0xf8] = MMX_OP2(psubb),
3068
    [0xf9] = MMX_OP2(psubw),
3069
    [0xfa] = MMX_OP2(psubl),
3070
    [0xfb] = MMX_OP2(psubq),
3071
    [0xfc] = MMX_OP2(paddb),
3072
    [0xfd] = MMX_OP2(paddw),
3073
    [0xfe] = MMX_OP2(paddl),
3074
};
3075

    
3076
static const SSEFunc_0_epp sse_op_table2[3 * 8][2] = {
3077
    [0 + 2] = MMX_OP2(psrlw),
3078
    [0 + 4] = MMX_OP2(psraw),
3079
    [0 + 6] = MMX_OP2(psllw),
3080
    [8 + 2] = MMX_OP2(psrld),
3081
    [8 + 4] = MMX_OP2(psrad),
3082
    [8 + 6] = MMX_OP2(pslld),
3083
    [16 + 2] = MMX_OP2(psrlq),
3084
    [16 + 3] = { NULL, gen_helper_psrldq_xmm },
3085
    [16 + 6] = MMX_OP2(psllq),
3086
    [16 + 7] = { NULL, gen_helper_pslldq_xmm },
3087
};
3088

    
3089
static const SSEFunc_0_epi sse_op_table3ai[] = {
3090
    gen_helper_cvtsi2ss,
3091
    gen_helper_cvtsi2sd
3092
};
3093

    
3094
#ifdef TARGET_X86_64
3095
static const SSEFunc_0_epl sse_op_table3aq[] = {
3096
    gen_helper_cvtsq2ss,
3097
    gen_helper_cvtsq2sd
3098
};
3099
#endif
3100

    
3101
static const SSEFunc_i_ep sse_op_table3bi[] = {
3102
    gen_helper_cvttss2si,
3103
    gen_helper_cvtss2si,
3104
    gen_helper_cvttsd2si,
3105
    gen_helper_cvtsd2si
3106
};
3107

    
3108
#ifdef TARGET_X86_64
3109
static const SSEFunc_l_ep sse_op_table3bq[] = {
3110
    gen_helper_cvttss2sq,
3111
    gen_helper_cvtss2sq,
3112
    gen_helper_cvttsd2sq,
3113
    gen_helper_cvtsd2sq
3114
};
3115
#endif
3116

    
3117
static const SSEFunc_0_epp sse_op_table4[8][4] = {
3118
    SSE_FOP(cmpeq),
3119
    SSE_FOP(cmplt),
3120
    SSE_FOP(cmple),
3121
    SSE_FOP(cmpunord),
3122
    SSE_FOP(cmpneq),
3123
    SSE_FOP(cmpnlt),
3124
    SSE_FOP(cmpnle),
3125
    SSE_FOP(cmpord),
3126
};
3127

    
3128
static const SSEFunc_0_epp sse_op_table5[256] = {
3129
    [0x0c] = gen_helper_pi2fw,
3130
    [0x0d] = gen_helper_pi2fd,
3131
    [0x1c] = gen_helper_pf2iw,
3132
    [0x1d] = gen_helper_pf2id,
3133
    [0x8a] = gen_helper_pfnacc,
3134
    [0x8e] = gen_helper_pfpnacc,
3135
    [0x90] = gen_helper_pfcmpge,
3136
    [0x94] = gen_helper_pfmin,
3137
    [0x96] = gen_helper_pfrcp,
3138
    [0x97] = gen_helper_pfrsqrt,
3139
    [0x9a] = gen_helper_pfsub,
3140
    [0x9e] = gen_helper_pfadd,
3141
    [0xa0] = gen_helper_pfcmpgt,
3142
    [0xa4] = gen_helper_pfmax,
3143
    [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
3144
    [0xa7] = gen_helper_movq, /* pfrsqit1 */
3145
    [0xaa] = gen_helper_pfsubr,
3146
    [0xae] = gen_helper_pfacc,
3147
    [0xb0] = gen_helper_pfcmpeq,
3148
    [0xb4] = gen_helper_pfmul,
3149
    [0xb6] = gen_helper_movq, /* pfrcpit2 */
3150
    [0xb7] = gen_helper_pmulhrw_mmx,
3151
    [0xbb] = gen_helper_pswapd,
3152
    [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
3153
};
3154

    
3155
struct SSEOpHelper_epp {
3156
    SSEFunc_0_epp op[2];
3157
    uint32_t ext_mask;
3158
};
3159

    
3160
struct SSEOpHelper_eppi {
3161
    SSEFunc_0_eppi op[2];
3162
    uint32_t ext_mask;
3163
};
3164

    
3165
#define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
3166
#define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
3167
#define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
3168
#define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
3169

    
3170
static const struct SSEOpHelper_epp sse_op_table6[256] = {
3171
    [0x00] = SSSE3_OP(pshufb),
3172
    [0x01] = SSSE3_OP(phaddw),
3173
    [0x02] = SSSE3_OP(phaddd),
3174
    [0x03] = SSSE3_OP(phaddsw),
3175
    [0x04] = SSSE3_OP(pmaddubsw),
3176
    [0x05] = SSSE3_OP(phsubw),
3177
    [0x06] = SSSE3_OP(phsubd),
3178
    [0x07] = SSSE3_OP(phsubsw),
3179
    [0x08] = SSSE3_OP(psignb),
3180
    [0x09] = SSSE3_OP(psignw),
3181
    [0x0a] = SSSE3_OP(psignd),
3182
    [0x0b] = SSSE3_OP(pmulhrsw),
3183
    [0x10] = SSE41_OP(pblendvb),
3184
    [0x14] = SSE41_OP(blendvps),
3185
    [0x15] = SSE41_OP(blendvpd),
3186
    [0x17] = SSE41_OP(ptest),
3187
    [0x1c] = SSSE3_OP(pabsb),
3188
    [0x1d] = SSSE3_OP(pabsw),
3189
    [0x1e] = SSSE3_OP(pabsd),
3190
    [0x20] = SSE41_OP(pmovsxbw),
3191
    [0x21] = SSE41_OP(pmovsxbd),
3192
    [0x22] = SSE41_OP(pmovsxbq),
3193
    [0x23] = SSE41_OP(pmovsxwd),
3194
    [0x24] = SSE41_OP(pmovsxwq),
3195
    [0x25] = SSE41_OP(pmovsxdq),
3196
    [0x28] = SSE41_OP(pmuldq),
3197
    [0x29] = SSE41_OP(pcmpeqq),
3198
    [0x2a] = SSE41_SPECIAL, /* movntqda */
3199
    [0x2b] = SSE41_OP(packusdw),
3200
    [0x30] = SSE41_OP(pmovzxbw),
3201
    [0x31] = SSE41_OP(pmovzxbd),
3202
    [0x32] = SSE41_OP(pmovzxbq),
3203
    [0x33] = SSE41_OP(pmovzxwd),
3204
    [0x34] = SSE41_OP(pmovzxwq),
3205
    [0x35] = SSE41_OP(pmovzxdq),
3206
    [0x37] = SSE42_OP(pcmpgtq),
3207
    [0x38] = SSE41_OP(pminsb),
3208
    [0x39] = SSE41_OP(pminsd),
3209
    [0x3a] = SSE41_OP(pminuw),
3210
    [0x3b] = SSE41_OP(pminud),
3211
    [0x3c] = SSE41_OP(pmaxsb),
3212
    [0x3d] = SSE41_OP(pmaxsd),
3213
    [0x3e] = SSE41_OP(pmaxuw),
3214
    [0x3f] = SSE41_OP(pmaxud),
3215
    [0x40] = SSE41_OP(pmulld),
3216
    [0x41] = SSE41_OP(phminposuw),
3217
};
3218

    
3219
static const struct SSEOpHelper_eppi sse_op_table7[256] = {
3220
    [0x08] = SSE41_OP(roundps),
3221
    [0x09] = SSE41_OP(roundpd),
3222
    [0x0a] = SSE41_OP(roundss),
3223
    [0x0b] = SSE41_OP(roundsd),
3224
    [0x0c] = SSE41_OP(blendps),
3225
    [0x0d] = SSE41_OP(blendpd),
3226
    [0x0e] = SSE41_OP(pblendw),
3227
    [0x0f] = SSSE3_OP(palignr),
3228
    [0x14] = SSE41_SPECIAL, /* pextrb */
3229
    [0x15] = SSE41_SPECIAL, /* pextrw */
3230
    [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */
3231
    [0x17] = SSE41_SPECIAL, /* extractps */
3232
    [0x20] = SSE41_SPECIAL, /* pinsrb */
3233
    [0x21] = SSE41_SPECIAL, /* insertps */
3234
    [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */
3235
    [0x40] = SSE41_OP(dpps),
3236
    [0x41] = SSE41_OP(dppd),
3237
    [0x42] = SSE41_OP(mpsadbw),
3238
    [0x60] = SSE42_OP(pcmpestrm),
3239
    [0x61] = SSE42_OP(pcmpestri),
3240
    [0x62] = SSE42_OP(pcmpistrm),
3241
    [0x63] = SSE42_OP(pcmpistri),
3242
};
3243

    
3244
static void gen_sse(CPUX86State *env, DisasContext *s, int b,
3245
                    target_ulong pc_start, int rex_r)
3246
{
3247
    int b1, op1_offset, op2_offset, is_xmm, val, ot;
3248
    int modrm, mod, rm, reg, reg_addr, offset_addr;
3249
    SSEFunc_0_epp sse_fn_epp;
3250
    SSEFunc_0_eppi sse_fn_eppi;
3251
    SSEFunc_0_ppi sse_fn_ppi;
3252
    SSEFunc_0_eppt sse_fn_eppt;
3253

    
3254
    b &= 0xff;
3255
    if (s->prefix & PREFIX_DATA)
3256
        b1 = 1;
3257
    else if (s->prefix & PREFIX_REPZ)
3258
        b1 = 2;
3259
    else if (s->prefix & PREFIX_REPNZ)
3260
        b1 = 3;
3261
    else
3262
        b1 = 0;
3263
    sse_fn_epp = sse_op_table1[b][b1];
3264
    if (!sse_fn_epp) {
3265
        goto illegal_op;
3266
    }
3267
    if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
3268
        is_xmm = 1;
3269
    } else {
3270
        if (b1 == 0) {
3271
            /* MMX case */
3272
            is_xmm = 0;
3273
        } else {
3274
            is_xmm = 1;
3275
        }
3276
    }
3277
    /* simple MMX/SSE operation */
3278
    if (s->flags & HF_TS_MASK) {
3279
        gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
3280
        return;
3281
    }
3282
    if (s->flags & HF_EM_MASK) {
3283
    illegal_op:
3284
        gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
3285
        return;
3286
    }
3287
    if (is_xmm && !(s->flags & HF_OSFXSR_MASK))
3288
        if ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))
3289
            goto illegal_op;
3290
    if (b == 0x0e) {
3291
        if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
3292
            goto illegal_op;
3293
        /* femms */
3294
        gen_helper_emms(cpu_env);
3295
        return;
3296
    }
3297
    if (b == 0x77) {
3298
        /* emms */
3299
        gen_helper_emms(cpu_env);
3300
        return;
3301
    }
3302
    /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3303
       the static cpu state) */
3304
    if (!is_xmm) {
3305
        gen_helper_enter_mmx(cpu_env);
3306
    }
3307

    
3308
    modrm = cpu_ldub_code(env, s->pc++);
3309
    reg = ((modrm >> 3) & 7);
3310
    if (is_xmm)
3311
        reg |= rex_r;
3312
    mod = (modrm >> 6) & 3;
3313
    if (sse_fn_epp == SSE_SPECIAL) {
3314
        b |= (b1 << 8);
3315
        switch(b) {
3316
        case 0x0e7: /* movntq */
3317
            if (mod == 3)
3318
                goto illegal_op;
3319
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3320
            gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
3321
            break;
3322
        case 0x1e7: /* movntdq */
3323
        case 0x02b: /* movntps */
3324
        case 0x12b: /* movntps */
3325
            if (mod == 3)
3326
                goto illegal_op;
3327
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3328
            gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3329
            break;
3330
        case 0x3f0: /* lddqu */
3331
            if (mod == 3)
3332
                goto illegal_op;
3333
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3334
            gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3335
            break;
3336
        case 0x22b: /* movntss */
3337
        case 0x32b: /* movntsd */
3338
            if (mod == 3)
3339
                goto illegal_op;
3340
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3341
            if (b1 & 1) {
3342
                gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,
3343
                    xmm_regs[reg]));
3344
            } else {
3345
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
3346
                    xmm_regs[reg].XMM_L(0)));
3347
                gen_op_st_T0_A0(OT_LONG + s->mem_index);
3348
            }
3349
            break;
3350
        case 0x6e: /* movd mm, ea */
3351
#ifdef TARGET_X86_64
3352
            if (s->dflag == 2) {
3353
                gen_ldst_modrm(env, s, modrm, OT_QUAD, OR_TMP0, 0);
3354
                tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,fpregs[reg].mmx));
3355
            } else
3356
#endif
3357
            {
3358
                gen_ldst_modrm(env, s, modrm, OT_LONG, OR_TMP0, 0);
3359
                tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
3360
                                 offsetof(CPUX86State,fpregs[reg].mmx));
3361
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3362
                gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32);
3363
            }
3364
            break;
3365
        case 0x16e: /* movd xmm, ea */
3366
#ifdef TARGET_X86_64
3367
            if (s->dflag == 2) {
3368
                gen_ldst_modrm(env, s, modrm, OT_QUAD, OR_TMP0, 0);
3369
                tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
3370
                                 offsetof(CPUX86State,xmm_regs[reg]));
3371
                gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T[0]);
3372
            } else
3373
#endif
3374
            {
3375
                gen_ldst_modrm(env, s, modrm, OT_LONG, OR_TMP0, 0);
3376
                tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
3377
                                 offsetof(CPUX86State,xmm_regs[reg]));
3378
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3379
                gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32);
3380
            }
3381
            break;
3382
        case 0x6f: /* movq mm, ea */
3383
            if (mod != 3) {
3384
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3385
                gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
3386
            } else {
3387
                rm = (modrm & 7);
3388
                tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
3389
                               offsetof(CPUX86State,fpregs[rm].mmx));
3390
                tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
3391
                               offsetof(CPUX86State,fpregs[reg].mmx));
3392
            }
3393
            break;
3394
        case 0x010: /* movups */
3395
        case 0x110: /* movupd */
3396
        case 0x028: /* movaps */
3397
        case 0x128: /* movapd */
3398
        case 0x16f: /* movdqa xmm, ea */
3399
        case 0x26f: /* movdqu xmm, ea */
3400
            if (mod != 3) {
3401
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3402
                gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3403
            } else {
3404
                rm = (modrm & 7) | REX_B(s);
3405
                gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
3406
                            offsetof(CPUX86State,xmm_regs[rm]));
3407
            }
3408
            break;
3409
        case 0x210: /* movss xmm, ea */
3410
            if (mod != 3) {
3411
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3412
                gen_op_ld_T0_A0(OT_LONG + s->mem_index);
3413
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3414
                gen_op_movl_T0_0();
3415
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
3416
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
3417
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
3418
            } else {
3419
                rm = (modrm & 7) | REX_B(s);
3420
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
3421
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
3422
            }
3423
            break;
3424
        case 0x310: /* movsd xmm, ea */
3425
            if (mod != 3) {
3426
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3427
                gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3428
                gen_op_movl_T0_0();
3429
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
3430
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
3431
            } else {
3432
                rm = (modrm & 7) | REX_B(s);
3433
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3434
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3435
            }
3436
            break;
3437
        case 0x012: /* movlps */
3438
        case 0x112: /* movlpd */
3439
            if (mod != 3) {
3440
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3441
                gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3442
            } else {
3443
                /* movhlps */
3444
                rm = (modrm & 7) | REX_B(s);
3445
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3446
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
3447
            }
3448
            break;
3449
        case 0x212: /* movsldup */
3450
            if (mod != 3) {
3451
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3452
                gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3453
            } else {
3454
                rm = (modrm & 7) | REX_B(s);
3455
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
3456
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
3457
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
3458
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(2)));
3459
            }
3460
            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
3461
                        offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3462
            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
3463
                        offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
3464
            break;
3465
        case 0x312: /* movddup */
3466
            if (mod != 3) {
3467
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3468
                gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3469
            } else {
3470
                rm = (modrm & 7) | REX_B(s);
3471
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3472
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3473
            }
3474
            gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
3475
                        offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3476
            break;
3477
        case 0x016: /* movhps */
3478
        case 0x116: /* movhpd */
3479
            if (mod != 3) {
3480
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3481
                gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3482
            } else {
3483
                /* movlhps */
3484
                rm = (modrm & 7) | REX_B(s);
3485
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
3486
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3487
            }
3488
            break;
3489
        case 0x216: /* movshdup */
3490
            if (mod != 3) {
3491
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3492
                gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3493
            } else {
3494
                rm = (modrm & 7) | REX_B(s);
3495
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
3496
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(1)));
3497
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
3498
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(3)));
3499
            }
3500
            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
3501
                        offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
3502
            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
3503
                        offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
3504
            break;
3505
        case 0x178:
3506
        case 0x378:
3507
            {
3508
                int bit_index, field_length;
3509

    
3510
                if (b1 == 1 && reg != 0)
3511
                    goto illegal_op;
3512
                field_length = cpu_ldub_code(env, s->pc++) & 0x3F;
3513
                bit_index = cpu_ldub_code(env, s->pc++) & 0x3F;
3514
                tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3515
                    offsetof(CPUX86State,xmm_regs[reg]));
3516
                if (b1 == 1)
3517
                    gen_helper_extrq_i(cpu_env, cpu_ptr0,
3518
                                       tcg_const_i32(bit_index),
3519
                                       tcg_const_i32(field_length));
3520
                else
3521
                    gen_helper_insertq_i(cpu_env, cpu_ptr0,
3522
                                         tcg_const_i32(bit_index),
3523
                                         tcg_const_i32(field_length));
3524
            }
3525
            break;
3526
        case 0x7e: /* movd ea, mm */
3527
#ifdef TARGET_X86_64
3528
            if (s->dflag == 2) {
3529
                tcg_gen_ld_i64(cpu_T[0], cpu_env, 
3530
                               offsetof(CPUX86State,fpregs[reg].mmx));
3531
                gen_ldst_modrm(env, s, modrm, OT_QUAD, OR_TMP0, 1);
3532
            } else
3533
#endif
3534
            {
3535
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
3536
                                 offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0)));
3537
                gen_ldst_modrm(env, s, modrm, OT_LONG, OR_TMP0, 1);
3538
            }
3539
            break;
3540
        case 0x17e: /* movd ea, xmm */
3541
#ifdef TARGET_X86_64
3542
            if (s->dflag == 2) {
3543
                tcg_gen_ld_i64(cpu_T[0], cpu_env, 
3544
                               offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3545
                gen_ldst_modrm(env, s, modrm, OT_QUAD, OR_TMP0, 1);
3546
            } else
3547
#endif
3548
            {
3549
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
3550
                                 offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3551
                gen_ldst_modrm(env, s, modrm, OT_LONG, OR_TMP0, 1);
3552
            }
3553
            break;
3554
        case 0x27e: /* movq xmm, ea */
3555
            if (mod != 3) {
3556
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3557
                gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3558
            } else {
3559
                rm = (modrm & 7) | REX_B(s);
3560
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3561
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3562
            }
3563
            gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3564
            break;
3565
        case 0x7f: /* movq ea, mm */
3566
            if (mod != 3) {
3567
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3568
                gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
3569
            } else {
3570
                rm = (modrm & 7);
3571
                gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
3572
                            offsetof(CPUX86State,fpregs[reg].mmx));
3573
            }
3574
            break;
3575
        case 0x011: /* movups */
3576
        case 0x111: /* movupd */
3577
        case 0x029: /* movaps */
3578
        case 0x129: /* movapd */
3579
        case 0x17f: /* movdqa ea, xmm */
3580
        case 0x27f: /* movdqu ea, xmm */
3581
            if (mod != 3) {
3582
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3583
                gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3584
            } else {
3585
                rm = (modrm & 7) | REX_B(s);
3586
                gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
3587
                            offsetof(CPUX86State,xmm_regs[reg]));
3588
            }
3589
            break;
3590
        case 0x211: /* movss ea, xmm */
3591
            if (mod != 3) {
3592
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3593
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3594
                gen_op_st_T0_A0(OT_LONG + s->mem_index);
3595
            } else {
3596
                rm = (modrm & 7) | REX_B(s);
3597
                gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)),
3598
                            offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3599
            }
3600
            break;
3601
        case 0x311: /* movsd ea, xmm */
3602
            if (mod != 3) {
3603
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3604
                gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3605
            } else {
3606
                rm = (modrm & 7) | REX_B(s);
3607
                gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
3608
                            offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3609
            }
3610
            break;
3611
        case 0x013: /* movlps */
3612
        case 0x113: /* movlpd */
3613
            if (mod != 3) {
3614
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3615
                gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3616
            } else {
3617
                goto illegal_op;
3618
            }
3619
            break;
3620
        case 0x017: /* movhps */
3621
        case 0x117: /* movhpd */
3622
            if (mod != 3) {
3623
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3624
                gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3625
            } else {
3626
                goto illegal_op;
3627
            }
3628
            break;
3629
        case 0x71: /* shift mm, im */
3630
        case 0x72:
3631
        case 0x73:
3632
        case 0x171: /* shift xmm, im */
3633
        case 0x172:
3634
        case 0x173:
3635
            if (b1 >= 2) {
3636
                goto illegal_op;
3637
            }
3638
            val = cpu_ldub_code(env, s->pc++);
3639
            if (is_xmm) {
3640
                gen_op_movl_T0_im(val);
3641
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
3642
                gen_op_movl_T0_0();
3643
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(1)));
3644
                op1_offset = offsetof(CPUX86State,xmm_t0);
3645
            } else {
3646
                gen_op_movl_T0_im(val);
3647
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0)));
3648
                gen_op_movl_T0_0();
3649
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1)));
3650
                op1_offset = offsetof(CPUX86State,mmx_t0);
3651
            }
3652
            sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
3653
                                       (((modrm >> 3)) & 7)][b1];
3654
            if (!sse_fn_epp) {
3655
                goto illegal_op;
3656
            }
3657
            if (is_xmm) {
3658
                rm = (modrm & 7) | REX_B(s);
3659
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3660
            } else {
3661
                rm = (modrm & 7);
3662
                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3663
            }
3664
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3665
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset);
3666
            sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3667
            break;
3668
        case 0x050: /* movmskps */
3669
            rm = (modrm & 7) | REX_B(s);
3670
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
3671
                             offsetof(CPUX86State,xmm_regs[rm]));
3672
            gen_helper_movmskps(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3673
            tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3674
            gen_op_mov_reg_T0(OT_LONG, reg);
3675
            break;
3676
        case 0x150: /* movmskpd */
3677
            rm = (modrm & 7) | REX_B(s);
3678
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
3679
                             offsetof(CPUX86State,xmm_regs[rm]));
3680
            gen_helper_movmskpd(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3681
            tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3682
            gen_op_mov_reg_T0(OT_LONG, reg);
3683
            break;
3684
        case 0x02a: /* cvtpi2ps */
3685
        case 0x12a: /* cvtpi2pd */
3686
            gen_helper_enter_mmx(cpu_env);
3687
            if (mod != 3) {
3688
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3689
                op2_offset = offsetof(CPUX86State,mmx_t0);
3690
                gen_ldq_env_A0(s->mem_index, op2_offset);
3691
            } else {
3692
                rm = (modrm & 7);
3693
                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3694
            }
3695
            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3696
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3697
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3698
            switch(b >> 8) {
3699
            case 0x0:
3700
                gen_helper_cvtpi2ps(cpu_env, cpu_ptr0, cpu_ptr1);
3701
                break;
3702
            default:
3703
            case 0x1:
3704
                gen_helper_cvtpi2pd(cpu_env, cpu_ptr0, cpu_ptr1);
3705
                break;
3706
            }
3707
            break;
3708
        case 0x22a: /* cvtsi2ss */
3709
        case 0x32a: /* cvtsi2sd */
3710
            ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3711
            gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3712
            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3713
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3714
            if (ot == OT_LONG) {
3715
                SSEFunc_0_epi sse_fn_epi = sse_op_table3ai[(b >> 8) & 1];
3716
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3717
                sse_fn_epi(cpu_env, cpu_ptr0, cpu_tmp2_i32);
3718
            } else {
3719
#ifdef TARGET_X86_64
3720
                SSEFunc_0_epl sse_fn_epl = sse_op_table3aq[(b >> 8) & 1];
3721
                sse_fn_epl(cpu_env, cpu_ptr0, cpu_T[0]);
3722
#else
3723
                goto illegal_op;
3724
#endif
3725
            }
3726
            break;
3727
        case 0x02c: /* cvttps2pi */
3728
        case 0x12c: /* cvttpd2pi */
3729
        case 0x02d: /* cvtps2pi */
3730
        case 0x12d: /* cvtpd2pi */
3731
            gen_helper_enter_mmx(cpu_env);
3732
            if (mod != 3) {
3733
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3734
                op2_offset = offsetof(CPUX86State,xmm_t0);
3735
                gen_ldo_env_A0(s->mem_index, op2_offset);
3736
            } else {
3737
                rm = (modrm & 7) | REX_B(s);
3738
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3739
            }
3740
            op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
3741
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3742
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3743
            switch(b) {
3744
            case 0x02c:
3745
                gen_helper_cvttps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3746
                break;
3747
            case 0x12c:
3748
                gen_helper_cvttpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3749
                break;
3750
            case 0x02d:
3751
                gen_helper_cvtps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3752
                break;
3753
            case 0x12d:
3754
                gen_helper_cvtpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3755
                break;
3756
            }
3757
            break;
3758
        case 0x22c: /* cvttss2si */
3759
        case 0x32c: /* cvttsd2si */
3760
        case 0x22d: /* cvtss2si */
3761
        case 0x32d: /* cvtsd2si */
3762
            ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3763
            if (mod != 3) {
3764
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3765
                if ((b >> 8) & 1) {
3766
                    gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_Q(0)));
3767
                } else {
3768
                    gen_op_ld_T0_A0(OT_LONG + s->mem_index);
3769
                    tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
3770
                }
3771
                op2_offset = offsetof(CPUX86State,xmm_t0);
3772
            } else {
3773
                rm = (modrm & 7) | REX_B(s);
3774
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3775
            }
3776
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3777
            if (ot == OT_LONG) {
3778
                SSEFunc_i_ep sse_fn_i_ep =
3779
                    sse_op_table3bi[((b >> 7) & 2) | (b & 1)];
3780
                sse_fn_i_ep(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3781
                tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3782
            } else {
3783
#ifdef TARGET_X86_64
3784
                SSEFunc_l_ep sse_fn_l_ep =
3785
                    sse_op_table3bq[((b >> 7) & 2) | (b & 1)];
3786
                sse_fn_l_ep(cpu_T[0], cpu_env, cpu_ptr0);
3787
#else
3788
                goto illegal_op;
3789
#endif
3790
            }
3791
            gen_op_mov_reg_T0(ot, reg);
3792
            break;
3793
        case 0xc4: /* pinsrw */
3794
        case 0x1c4:
3795
            s->rip_offset = 1;
3796
            gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
3797
            val = cpu_ldub_code(env, s->pc++);
3798
            if (b1) {
3799
                val &= 7;
3800
                tcg_gen_st16_tl(cpu_T[0], cpu_env,
3801
                                offsetof(CPUX86State,xmm_regs[reg].XMM_W(val)));
3802
            } else {
3803
                val &= 3;
3804
                tcg_gen_st16_tl(cpu_T[0], cpu_env,
3805
                                offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val)));
3806
            }
3807
            break;
3808
        case 0xc5: /* pextrw */
3809
        case 0x1c5:
3810
            if (mod != 3)
3811
                goto illegal_op;
3812
            ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3813
            val = cpu_ldub_code(env, s->pc++);
3814
            if (b1) {
3815
                val &= 7;
3816
                rm = (modrm & 7) | REX_B(s);
3817
                tcg_gen_ld16u_tl(cpu_T[0], cpu_env,
3818
                                 offsetof(CPUX86State,xmm_regs[rm].XMM_W(val)));
3819
            } else {
3820
                val &= 3;
3821
                rm = (modrm & 7);
3822
                tcg_gen_ld16u_tl(cpu_T[0], cpu_env,
3823
                                offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
3824
            }
3825
            reg = ((modrm >> 3) & 7) | rex_r;
3826
            gen_op_mov_reg_T0(ot, reg);
3827
            break;
3828
        case 0x1d6: /* movq ea, xmm */
3829
            if (mod != 3) {
3830
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3831
                gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3832
            } else {
3833
                rm = (modrm & 7) | REX_B(s);
3834
                gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
3835
                            offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3836
                gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
3837
            }
3838
            break;
3839
        case 0x2d6: /* movq2dq */
3840
            gen_helper_enter_mmx(cpu_env);
3841
            rm = (modrm & 7);
3842
            gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3843
                        offsetof(CPUX86State,fpregs[rm].mmx));
3844
            gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3845
            break;
3846
        case 0x3d6: /* movdq2q */
3847
            gen_helper_enter_mmx(cpu_env);
3848
            rm = (modrm & 7) | REX_B(s);
3849
            gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
3850
                        offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3851
            break;
3852
        case 0xd7: /* pmovmskb */
3853
        case 0x1d7:
3854
            if (mod != 3)
3855
                goto illegal_op;
3856
            if (b1) {
3857
                rm = (modrm & 7) | REX_B(s);
3858
                tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm]));
3859
                gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3860
            } else {
3861
                rm = (modrm & 7);
3862
                tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx));
3863
                gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3864
            }
3865
            tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3866
            reg = ((modrm >> 3) & 7) | rex_r;
3867
            gen_op_mov_reg_T0(OT_LONG, reg);
3868
            break;
3869

    
3870
        case 0x138:
3871
        case 0x038:
3872
            b = modrm;
3873
            if ((b & 0xf0) == 0xf0) {
3874
                goto do_0f_38_fx;
3875
            }
3876
            modrm = cpu_ldub_code(env, s->pc++);
3877
            rm = modrm & 7;
3878
            reg = ((modrm >> 3) & 7) | rex_r;
3879
            mod = (modrm >> 6) & 3;
3880
            if (b1 >= 2) {
3881
                goto illegal_op;
3882
            }
3883

    
3884
            sse_fn_epp = sse_op_table6[b].op[b1];
3885
            if (!sse_fn_epp) {
3886
                goto illegal_op;
3887
            }
3888
            if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
3889
                goto illegal_op;
3890

    
3891
            if (b1) {
3892
                op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3893
                if (mod == 3) {
3894
                    op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
3895
                } else {
3896
                    op2_offset = offsetof(CPUX86State,xmm_t0);
3897
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3898
                    switch (b) {
3899
                    case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3900
                    case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3901
                    case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3902
                        gen_ldq_env_A0(s->mem_index, op2_offset +
3903
                                        offsetof(XMMReg, XMM_Q(0)));
3904
                        break;
3905
                    case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3906
                    case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3907
                        tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
3908
                                          (s->mem_index >> 2) - 1);
3909
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
3910
                        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset +
3911
                                        offsetof(XMMReg, XMM_L(0)));
3912
                        break;
3913
                    case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3914
                        tcg_gen_qemu_ld16u(cpu_tmp0, cpu_A0,
3915
                                          (s->mem_index >> 2) - 1);
3916
                        tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset +
3917
                                        offsetof(XMMReg, XMM_W(0)));
3918
                        break;
3919
                    case 0x2a:            /* movntqda */
3920
                        gen_ldo_env_A0(s->mem_index, op1_offset);
3921
                        return;
3922
                    default:
3923
                        gen_ldo_env_A0(s->mem_index, op2_offset);
3924
                    }
3925
                }
3926
            } else {
3927
                op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3928
                if (mod == 3) {
3929
                    op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3930
                } else {
3931
                    op2_offset = offsetof(CPUX86State,mmx_t0);
3932
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3933
                    gen_ldq_env_A0(s->mem_index, op2_offset);
3934
                }
3935
            }
3936
            if (sse_fn_epp == SSE_SPECIAL) {
3937
                goto illegal_op;
3938
            }
3939

    
3940
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3941
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3942
            sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3943

    
3944
            if (b == 0x17) {
3945
                set_cc_op(s, CC_OP_EFLAGS);
3946
            }
3947
            break;
3948

    
3949
        case 0x238:
3950
        case 0x338:
3951
        do_0f_38_fx:
3952
            /* Various integer extensions at 0f 38 f[0-f].  */
3953
            b = modrm | (b1 << 8);
3954
            modrm = cpu_ldub_code(env, s->pc++);
3955
            reg = ((modrm >> 3) & 7) | rex_r;
3956

    
3957
            switch (b) {
3958
            case 0x3f0: /* crc32 Gd,Eb */
3959
            case 0x3f1: /* crc32 Gd,Ey */
3960
            do_crc32:
3961
                if (!(s->cpuid_ext_features & CPUID_EXT_SSE42)) {
3962
                    goto illegal_op;
3963
                }
3964
                if ((b & 0xff) == 0xf0) {
3965
                    ot = OT_BYTE;
3966
                } else if (s->dflag != 2) {
3967
                    ot = (s->prefix & PREFIX_DATA ? OT_WORD : OT_LONG);
3968
                } else {
3969
                    ot = OT_QUAD;
3970
                }
3971

    
3972
                gen_op_mov_TN_reg(OT_LONG, 0, reg);
3973
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3974
                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3975
                gen_helper_crc32(cpu_T[0], cpu_tmp2_i32,
3976
                                 cpu_T[0], tcg_const_i32(8 << ot));
3977

    
3978
                ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3979
                gen_op_mov_reg_T0(ot, reg);
3980
                break;
3981

    
3982
            case 0x1f0: /* crc32 or movbe */
3983
            case 0x1f1:
3984
                /* For these insns, the f3 prefix is supposed to have priority
3985
                   over the 66 prefix, but that's not what we implement above
3986
                   setting b1.  */
3987
                if (s->prefix & PREFIX_REPNZ) {
3988
                    goto do_crc32;
3989
                }
3990
                /* FALLTHRU */
3991
            case 0x0f0: /* movbe Gy,My */
3992
            case 0x0f1: /* movbe My,Gy */
3993
                if (!(s->cpuid_ext_features & CPUID_EXT_MOVBE)) {
3994
                    goto illegal_op;
3995
                }
3996
                if (s->dflag != 2) {
3997
                    ot = (s->prefix & PREFIX_DATA ? OT_WORD : OT_LONG);
3998
                } else {
3999
                    ot = OT_QUAD;
4000
                }
4001

    
4002
                /* Load the data incoming to the bswap.  Note that the TCG
4003
                   implementation of bswap requires the input be zero
4004
                   extended.  In the case of the loads, we simply know that
4005
                   gen_op_ld_v via gen_ldst_modrm does that already.  */
4006
                if ((b & 1) == 0) {
4007
                    gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4008
                } else {
4009
                    switch (ot) {
4010
                    case OT_WORD:
4011
                        tcg_gen_ext16u_tl(cpu_T[0], cpu_regs[reg]);
4012
                        break;
4013
                    default:
4014
                        tcg_gen_ext32u_tl(cpu_T[0], cpu_regs[reg]);
4015
                        break;
4016
                    case OT_QUAD:
4017
                        tcg_gen_mov_tl(cpu_T[0], cpu_regs[reg]);
4018
                        break;
4019
                    }
4020
                }
4021

    
4022
                switch (ot) {
4023
                case OT_WORD:
4024
                    tcg_gen_bswap16_tl(cpu_T[0], cpu_T[0]);
4025
                    break;
4026
                default:
4027
                    tcg_gen_bswap32_tl(cpu_T[0], cpu_T[0]);
4028
                    break;
4029
#ifdef TARGET_X86_64
4030
                case OT_QUAD:
4031
                    tcg_gen_bswap64_tl(cpu_T[0], cpu_T[0]);
4032
                    break;
4033
#endif
4034
                }
4035

    
4036
                if ((b & 1) == 0) {
4037
                    gen_op_mov_reg_T0(ot, reg);
4038
                } else {
4039
                    gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
4040
                }
4041
                break;
4042

    
4043
            case 0x0f2: /* andn Gy, By, Ey */
4044
                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
4045
                    || !(s->prefix & PREFIX_VEX)
4046
                    || s->vex_l != 0) {
4047
                    goto illegal_op;
4048
                }
4049
                ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
4050
                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4051
                tcg_gen_andc_tl(cpu_T[0], cpu_regs[s->vex_v], cpu_T[0]);
4052
                gen_op_mov_reg_T0(ot, reg);
4053
                gen_op_update1_cc();
4054
                set_cc_op(s, CC_OP_LOGICB + ot);
4055
                break;
4056

    
4057
            case 0x0f7: /* bextr Gy, Ey, By */
4058
                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
4059
                    || !(s->prefix & PREFIX_VEX)
4060
                    || s->vex_l != 0) {
4061
                    goto illegal_op;
4062
                }
4063
                ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
4064
                {
4065
                    TCGv bound, zero;
4066

    
4067
                    gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4068
                    /* Extract START, and shift the operand.
4069
                       Shifts larger than operand size get zeros.  */
4070
                    tcg_gen_ext8u_tl(cpu_A0, cpu_regs[s->vex_v]);
4071
                    tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_A0);
4072

    
4073
                    bound = tcg_const_tl(ot == OT_QUAD ? 63 : 31);
4074
                    zero = tcg_const_tl(0);
4075
                    tcg_gen_movcond_tl(TCG_COND_LEU, cpu_T[0], cpu_A0, bound,
4076
                                       cpu_T[0], zero);
4077
                    tcg_temp_free(zero);
4078

    
4079
                    /* Extract the LEN into a mask.  Lengths larger than
4080
                       operand size get all ones.  */
4081
                    tcg_gen_shri_tl(cpu_A0, cpu_regs[s->vex_v], 8);
4082
                    tcg_gen_ext8u_tl(cpu_A0, cpu_A0);
4083
                    tcg_gen_movcond_tl(TCG_COND_LEU, cpu_A0, cpu_A0, bound,
4084
                                       cpu_A0, bound);
4085
                    tcg_temp_free(bound);
4086
                    tcg_gen_movi_tl(cpu_T[1], 1);
4087
                    tcg_gen_shl_tl(cpu_T[1], cpu_T[1], cpu_A0);
4088
                    tcg_gen_subi_tl(cpu_T[1], cpu_T[1], 1);
4089
                    tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4090

    
4091
                    gen_op_mov_reg_T0(ot, reg);
4092
                    gen_op_update1_cc();
4093
                    set_cc_op(s, CC_OP_LOGICB + ot);
4094
                }
4095
                break;
4096

    
4097
            case 0x0f5: /* bzhi Gy, Ey, By */
4098
                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4099
                    || !(s->prefix & PREFIX_VEX)
4100
                    || s->vex_l != 0) {
4101
                    goto illegal_op;
4102
                }
4103
                ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
4104
                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4105
                tcg_gen_ext8u_tl(cpu_T[1], cpu_regs[s->vex_v]);
4106
                {
4107
                    TCGv bound = tcg_const_tl(ot == OT_QUAD ? 63 : 31);
4108
                    /* Note that since we're using BMILG (in order to get O
4109
                       cleared) we need to store the inverse into C.  */
4110
                    tcg_gen_setcond_tl(TCG_COND_LT, cpu_cc_src,
4111
                                       cpu_T[1], bound);
4112
                    tcg_gen_movcond_tl(TCG_COND_GT, cpu_T[1], cpu_T[1],
4113
                                       bound, bound, cpu_T[1]);
4114
                    tcg_temp_free(bound);
4115
                }
4116
                tcg_gen_movi_tl(cpu_A0, -1);
4117
                tcg_gen_shl_tl(cpu_A0, cpu_A0, cpu_T[1]);
4118
                tcg_gen_andc_tl(cpu_T[0], cpu_T[0], cpu_A0);
4119
                gen_op_mov_reg_T0(ot, reg);
4120
                gen_op_update1_cc();
4121
                set_cc_op(s, CC_OP_BMILGB + ot);
4122
                break;
4123

    
4124
            case 0x3f6: /* mulx By, Gy, rdx, Ey */
4125
                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4126
                    || !(s->prefix & PREFIX_VEX)
4127
                    || s->vex_l != 0) {
4128
                    goto illegal_op;
4129
                }
4130
                ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
4131
                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4132
                switch (ot) {
4133
                    TCGv_i64 t0, t1;
4134
                default:
4135
                    t0 = tcg_temp_new_i64();
4136
                    t1 = tcg_temp_new_i64();
4137
#ifdef TARGET_X86_64
4138
                    tcg_gen_ext32u_i64(t0, cpu_T[0]);
4139
                    tcg_gen_ext32u_i64(t1, cpu_regs[R_EDX]);
4140
#else
4141
                    tcg_gen_extu_i32_i64(t0, cpu_T[0]);
4142
                    tcg_gen_extu_i32_i64(t0, cpu_regs[R_EDX]);
4143
#endif
4144
                    tcg_gen_mul_i64(t0, t0, t1);
4145
                    tcg_gen_trunc_i64_tl(cpu_T[0], t0);
4146
                    tcg_gen_shri_i64(t0, t0, 32);
4147
                    tcg_gen_trunc_i64_tl(cpu_T[1], t0);
4148
                    tcg_temp_free_i64(t0);
4149
                    tcg_temp_free_i64(t1);
4150
                    gen_op_mov_reg_T0(OT_LONG, s->vex_v);
4151
                    gen_op_mov_reg_T1(OT_LONG, reg);
4152
                    break;
4153
#ifdef TARGET_X86_64
4154
                case OT_QUAD:
4155
                    tcg_gen_mov_tl(cpu_T[1], cpu_regs[R_EDX]);
4156
                    tcg_gen_mul_tl(cpu_regs[s->vex_v], cpu_T[0], cpu_T[1]);
4157
                    gen_helper_umulh(cpu_regs[reg], cpu_T[0], cpu_T[1]);
4158
                    break;
4159
#endif
4160
                }
4161
                break;
4162

    
4163
            case 0x3f5: /* pdep Gy, By, Ey */
4164
                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4165
                    || !(s->prefix & PREFIX_VEX)
4166
                    || s->vex_l != 0) {
4167
                    goto illegal_op;
4168
                }
4169
                ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
4170
                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4171
                /* Note that by zero-extending the mask operand, we
4172
                   automatically handle zero-extending the result.  */
4173
                if (s->dflag == 2) {
4174
                    tcg_gen_mov_tl(cpu_T[1], cpu_regs[s->vex_v]);
4175
                } else {
4176
                    tcg_gen_ext32u_tl(cpu_T[1], cpu_regs[s->vex_v]);
4177
                }
4178
                gen_helper_pdep(cpu_regs[reg], cpu_T[0], cpu_T[1]);
4179
                break;
4180

    
4181
            case 0x2f5: /* pext Gy, By, Ey */
4182
                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4183
                    || !(s->prefix & PREFIX_VEX)
4184
                    || s->vex_l != 0) {
4185
                    goto illegal_op;
4186
                }
4187
                ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
4188
                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4189
                /* Note that by zero-extending the mask operand, we
4190
                   automatically handle zero-extending the result.  */
4191
                if (s->dflag == 2) {
4192
                    tcg_gen_mov_tl(cpu_T[1], cpu_regs[s->vex_v]);
4193
                } else {
4194
                    tcg_gen_ext32u_tl(cpu_T[1], cpu_regs[s->vex_v]);
4195
                }
4196
                gen_helper_pext(cpu_regs[reg], cpu_T[0], cpu_T[1]);
4197
                break;
4198

    
4199
            case 0x1f6: /* adcx Gy, Ey */
4200
            case 0x2f6: /* adox Gy, Ey */
4201
                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_ADX)) {
4202
                    goto illegal_op;
4203
                } else {
4204
                    TCGv carry_in, carry_out;
4205
                    int end_op;
4206

    
4207
                    ot = (s->dflag == 2 ? OT_QUAD : OT_LONG);
4208
                    gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4209

    
4210
                    /* Re-use the carry-out from a previous round.  */
4211
                    TCGV_UNUSED(carry_in);
4212
                    carry_out = (b == 0x1f6 ? cpu_cc_dst : cpu_cc_src2);
4213
                    switch (s->cc_op) {
4214
                    case CC_OP_ADCX:
4215
                        if (b == 0x1f6) {
4216
                            carry_in = cpu_cc_dst;
4217
                            end_op = CC_OP_ADCX;
4218
                        } else {
4219
                            end_op = CC_OP_ADCOX;
4220
                        }
4221
                        break;
4222
                    case CC_OP_ADOX:
4223
                        if (b == 0x1f6) {
4224
                            end_op = CC_OP_ADCOX;
4225
                        } else {
4226
                            carry_in = cpu_cc_src2;
4227
                            end_op = CC_OP_ADOX;
4228
                        }
4229
                        break;
4230
                    case CC_OP_ADCOX:
4231
                        end_op = CC_OP_ADCOX;
4232
                        carry_in = carry_out;
4233
                        break;
4234
                    default:
4235
                        end_op = (b == 0x1f6 ? CC_OP_ADCX : CC_OP_ADCOX);
4236
                        break;
4237
                    }
4238
                    /* If we can't reuse carry-out, get it out of EFLAGS.  */
4239
                    if (TCGV_IS_UNUSED(carry_in)) {
4240
                        if (s->cc_op != CC_OP_ADCX && s->cc_op != CC_OP_ADOX) {
4241
                            gen_compute_eflags(s);
4242
                        }
4243
                        carry_in = cpu_tmp0;
4244
                        tcg_gen_shri_tl(carry_in, cpu_cc_src,
4245
                                        ctz32(b == 0x1f6 ? CC_C : CC_O));
4246
                        tcg_gen_andi_tl(carry_in, carry_in, 1);
4247
                    }
4248

    
4249
                    switch (ot) {
4250
#ifdef TARGET_X86_64
4251
                    case OT_LONG:
4252
                        /* If we know TL is 64-bit, and we want a 32-bit
4253
                           result, just do everything in 64-bit arithmetic.  */
4254
                        tcg_gen_ext32u_i64(cpu_regs[reg], cpu_regs[reg]);
4255
                        tcg_gen_ext32u_i64(cpu_T[0], cpu_T[0]);
4256
                        tcg_gen_add_i64(cpu_T[0], cpu_T[0], cpu_regs[reg]);
4257
                        tcg_gen_add_i64(cpu_T[0], cpu_T[0], carry_in);
4258
                        tcg_gen_ext32u_i64(cpu_regs[reg], cpu_T[0]);
4259
                        tcg_gen_shri_i64(carry_out, cpu_T[0], 32);
4260
                        break;
4261
#endif
4262
                    default:
4263
                        /* Otherwise compute the carry-out in two steps.  */
4264
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_regs[reg]);
4265
                        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_tmp4,
4266
                                           cpu_T[0], cpu_regs[reg]);
4267
                        tcg_gen_add_tl(cpu_regs[reg], cpu_T[0], carry_in);
4268
                        tcg_gen_setcond_tl(TCG_COND_LTU, carry_out,
4269
                                           cpu_regs[reg], cpu_T[0]);
4270
                        tcg_gen_or_tl(carry_out, carry_out, cpu_tmp4);
4271
                        break;
4272
                    }
4273
                    /* We began with all flags computed to CC_SRC, and we
4274
                       have now placed the carry-out in CC_DST.  All that
4275
                       is left is to record the CC_OP.  */
4276
                    set_cc_op(s, end_op);
4277
                }
4278
                break;
4279

    
4280
            case 0x1f7: /* shlx Gy, Ey, By */
4281
            case 0x2f7: /* sarx Gy, Ey, By */
4282
            case 0x3f7: /* shrx Gy, Ey, By */
4283
                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4284
                    || !(s->prefix & PREFIX_VEX)
4285
                    || s->vex_l != 0) {
4286
                    goto illegal_op;
4287
                }
4288
                ot = (s->dflag == 2 ? OT_QUAD : OT_LONG);
4289
                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4290
                if (ot == OT_QUAD) {
4291
                    tcg_gen_andi_tl(cpu_T[1], cpu_regs[s->vex_v], 63);
4292
                } else {
4293
                    tcg_gen_andi_tl(cpu_T[1], cpu_regs[s->vex_v], 31);
4294
                }
4295
                if (b == 0x1f7) {
4296
                    tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4297
                } else if (b == 0x2f7) {
4298
                    if (ot != OT_QUAD) {
4299
                        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4300
                    }
4301
                    tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4302
                } else {
4303
                    if (ot != OT_QUAD) {
4304
                        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
4305
                    }
4306
                    tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4307
                }
4308
                gen_op_mov_reg_T0(ot, reg);
4309
                break;
4310

    
4311
            case 0x0f3:
4312
            case 0x1f3:
4313
            case 0x2f3:
4314
            case 0x3f3: /* Group 17 */
4315
                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
4316
                    || !(s->prefix & PREFIX_VEX)
4317
                    || s->vex_l != 0) {
4318
                    goto illegal_op;
4319
                }
4320
                ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
4321
                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4322

    
4323
                switch (reg & 7) {
4324
                case 1: /* blsr By,Ey */
4325
                    tcg_gen_neg_tl(cpu_T[1], cpu_T[0]);
4326
                    tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4327
                    gen_op_mov_reg_T0(ot, s->vex_v);
4328
                    gen_op_update2_cc();
4329
                    set_cc_op(s, CC_OP_BMILGB + ot);
4330
                    break;
4331

    
4332
                case 2: /* blsmsk By,Ey */
4333
                    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4334
                    tcg_gen_subi_tl(cpu_T[0], cpu_T[0], 1);
4335
                    tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_cc_src);
4336
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4337
                    set_cc_op(s, CC_OP_BMILGB + ot);
4338
                    break;
4339

    
4340
                case 3: /* blsi By, Ey */
4341
                    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4342
                    tcg_gen_subi_tl(cpu_T[0], cpu_T[0], 1);
4343
                    tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_cc_src);
4344
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4345
                    set_cc_op(s, CC_OP_BMILGB + ot);
4346
                    break;
4347

    
4348
                default:
4349
                    goto illegal_op;
4350
                }
4351
                break;
4352

    
4353
            default:
4354
                goto illegal_op;
4355
            }
4356
            break;
4357

    
4358
        case 0x03a:
4359
        case 0x13a:
4360
            b = modrm;
4361
            modrm = cpu_ldub_code(env, s->pc++);
4362
            rm = modrm & 7;
4363
            reg = ((modrm >> 3) & 7) | rex_r;
4364
            mod = (modrm >> 6) & 3;
4365
            if (b1 >= 2) {
4366
                goto illegal_op;
4367
            }
4368

    
4369
            sse_fn_eppi = sse_op_table7[b].op[b1];
4370
            if (!sse_fn_eppi) {
4371
                goto illegal_op;
4372
            }
4373
            if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
4374
                goto illegal_op;
4375

    
4376
            if (sse_fn_eppi == SSE_SPECIAL) {
4377
                ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
4378
                rm = (modrm & 7) | REX_B(s);
4379
                if (mod != 3)
4380
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4381
                reg = ((modrm >> 3) & 7) | rex_r;
4382
                val = cpu_ldub_code(env, s->pc++);
4383
                switch (b) {
4384
                case 0x14: /* pextrb */
4385
                    tcg_gen_ld8u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
4386
                                            xmm_regs[reg].XMM_B(val & 15)));
4387
                    if (mod == 3)
4388
                        gen_op_mov_reg_T0(ot, rm);
4389
                    else
4390
                        tcg_gen_qemu_st8(cpu_T[0], cpu_A0,
4391
                                        (s->mem_index >> 2) - 1);
4392
                    break;
4393
                case 0x15: /* pextrw */
4394
                    tcg_gen_ld16u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
4395
                                            xmm_regs[reg].XMM_W(val & 7)));
4396
                    if (mod == 3)
4397
                        gen_op_mov_reg_T0(ot, rm);
4398
                    else
4399
                        tcg_gen_qemu_st16(cpu_T[0], cpu_A0,
4400
                                        (s->mem_index >> 2) - 1);
4401
                    break;
4402
                case 0x16:
4403
                    if (ot == OT_LONG) { /* pextrd */
4404
                        tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4405
                                        offsetof(CPUX86State,
4406
                                                xmm_regs[reg].XMM_L(val & 3)));
4407
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
4408
                        if (mod == 3)
4409
                            gen_op_mov_reg_v(ot, rm, cpu_T[0]);
4410
                        else
4411
                            tcg_gen_qemu_st32(cpu_T[0], cpu_A0,
4412
                                            (s->mem_index >> 2) - 1);
4413
                    } else { /* pextrq */
4414
#ifdef TARGET_X86_64
4415
                        tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
4416
                                        offsetof(CPUX86State,
4417
                                                xmm_regs[reg].XMM_Q(val & 1)));
4418
                        if (mod == 3)
4419
                            gen_op_mov_reg_v(ot, rm, cpu_tmp1_i64);
4420
                        else
4421
                            tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0,
4422
                                            (s->mem_index >> 2) - 1);
4423
#else
4424
                        goto illegal_op;
4425
#endif
4426
                    }
4427
                    break;
4428
                case 0x17: /* extractps */
4429
                    tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
4430
                                            xmm_regs[reg].XMM_L(val & 3)));
4431
                    if (mod == 3)
4432
                        gen_op_mov_reg_T0(ot, rm);
4433
                    else
4434
                        tcg_gen_qemu_st32(cpu_T[0], cpu_A0,
4435
                                        (s->mem_index >> 2) - 1);
4436
                    break;
4437
                case 0x20: /* pinsrb */
4438
                    if (mod == 3)
4439
                        gen_op_mov_TN_reg(OT_LONG, 0, rm);
4440
                    else
4441
                        tcg_gen_qemu_ld8u(cpu_tmp0, cpu_A0,
4442
                                        (s->mem_index >> 2) - 1);
4443
                    tcg_gen_st8_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State,
4444
                                            xmm_regs[reg].XMM_B(val & 15)));
4445
                    break;
4446
                case 0x21: /* insertps */
4447
                    if (mod == 3) {
4448
                        tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4449
                                        offsetof(CPUX86State,xmm_regs[rm]
4450
                                                .XMM_L((val >> 6) & 3)));
4451
                    } else {
4452
                        tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
4453
                                        (s->mem_index >> 2) - 1);
4454
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
4455
                    }
4456
                    tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4457
                                    offsetof(CPUX86State,xmm_regs[reg]
4458
                                            .XMM_L((val >> 4) & 3)));
4459
                    if ((val >> 0) & 1)
4460
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4461
                                        cpu_env, offsetof(CPUX86State,
4462
                                                xmm_regs[reg].XMM_L(0)));
4463
                    if ((val >> 1) & 1)
4464
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4465
                                        cpu_env, offsetof(CPUX86State,
4466
                                                xmm_regs[reg].XMM_L(1)));
4467
                    if ((val >> 2) & 1)
4468
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4469
                                        cpu_env, offsetof(CPUX86State,
4470
                                                xmm_regs[reg].XMM_L(2)));
4471
                    if ((val >> 3) & 1)
4472
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4473
                                        cpu_env, offsetof(CPUX86State,
4474
                                                xmm_regs[reg].XMM_L(3)));
4475
                    break;
4476
                case 0x22:
4477
                    if (ot == OT_LONG) { /* pinsrd */
4478
                        if (mod == 3)
4479
                            gen_op_mov_v_reg(ot, cpu_tmp0, rm);
4480
                        else
4481
                            tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
4482
                                            (s->mem_index >> 2) - 1);
4483
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
4484
                        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4485
                                        offsetof(CPUX86State,
4486
                                                xmm_regs[reg].XMM_L(val & 3)));
4487
                    } else { /* pinsrq */
4488
#ifdef TARGET_X86_64
4489
                        if (mod == 3)
4490
                            gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);
4491
                        else
4492
                            tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0,
4493
                                            (s->mem_index >> 2) - 1);
4494
                        tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
4495
                                        offsetof(CPUX86State,
4496
                                                xmm_regs[reg].XMM_Q(val & 1)));
4497
#else
4498
                        goto illegal_op;
4499
#endif
4500
                    }
4501
                    break;
4502
                }
4503
                return;
4504
            }
4505

    
4506
            if (b1) {
4507
                op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4508
                if (mod == 3) {
4509
                    op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
4510
                } else {
4511
                    op2_offset = offsetof(CPUX86State,xmm_t0);
4512
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4513
                    gen_ldo_env_A0(s->mem_index, op2_offset);
4514
                }
4515
            } else {
4516
                op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4517
                if (mod == 3) {
4518
                    op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4519
                } else {
4520
                    op2_offset = offsetof(CPUX86State,mmx_t0);
4521
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4522
                    gen_ldq_env_A0(s->mem_index, op2_offset);
4523
                }
4524
            }
4525
            val = cpu_ldub_code(env, s->pc++);
4526

    
4527
            if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
4528
                set_cc_op(s, CC_OP_EFLAGS);
4529

    
4530
                if (s->dflag == 2)
4531
                    /* The helper must use entire 64-bit gp registers */
4532
                    val |= 1 << 8;
4533
            }
4534

    
4535
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4536
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4537
            sse_fn_eppi(cpu_env, cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4538
            break;
4539

    
4540
        case 0x33a:
4541
            /* Various integer extensions at 0f 3a f[0-f].  */
4542
            b = modrm | (b1 << 8);
4543
            modrm = cpu_ldub_code(env, s->pc++);
4544
            reg = ((modrm >> 3) & 7) | rex_r;
4545

    
4546
            switch (b) {
4547
            case 0x3f0: /* rorx Gy,Ey, Ib */
4548
                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4549
                    || !(s->prefix & PREFIX_VEX)
4550
                    || s->vex_l != 0) {
4551
                    goto illegal_op;
4552
                }
4553
                ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
4554
                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4555
                b = cpu_ldub_code(env, s->pc++);
4556
                if (ot == OT_QUAD) {
4557
                    tcg_gen_rotri_tl(cpu_T[0], cpu_T[0], b & 63);
4558
                } else {
4559
                    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4560
                    tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, b & 31);
4561
                    tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
4562
                }
4563
                gen_op_mov_reg_T0(ot, reg);
4564
                break;
4565

    
4566
            default:
4567
                goto illegal_op;
4568
            }
4569
            break;
4570

    
4571
        default:
4572
            goto illegal_op;
4573
        }
4574
    } else {
4575
        /* generic MMX or SSE operation */
4576
        switch(b) {
4577
        case 0x70: /* pshufx insn */
4578
        case 0xc6: /* pshufx insn */
4579
        case 0xc2: /* compare insns */
4580
            s->rip_offset = 1;
4581
            break;
4582
        default:
4583
            break;
4584
        }
4585
        if (is_xmm) {
4586
            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4587
            if (mod != 3) {
4588
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4589
                op2_offset = offsetof(CPUX86State,xmm_t0);
4590
                if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f && b != 0x5b) ||
4591
                                b == 0xc2)) {
4592
                    /* specific case for SSE single instructions */
4593
                    if (b1 == 2) {
4594
                        /* 32 bit access */
4595
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
4596
                        tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
4597
                    } else {
4598
                        /* 64 bit access */
4599
                        gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_D(0)));
4600
                    }
4601
                } else {
4602
                    gen_ldo_env_A0(s->mem_index, op2_offset);
4603
                }
4604
            } else {
4605
                rm = (modrm & 7) | REX_B(s);
4606
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
4607
            }
4608
        } else {
4609
            op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4610
            if (mod != 3) {
4611
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4612
                op2_offset = offsetof(CPUX86State,mmx_t0);
4613
                gen_ldq_env_A0(s->mem_index, op2_offset);
4614
            } else {
4615
                rm = (modrm & 7);
4616
                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4617
            }
4618
        }
4619
        switch(b) {
4620
        case 0x0f: /* 3DNow! data insns */
4621
            if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
4622
                goto illegal_op;
4623
            val = cpu_ldub_code(env, s->pc++);
4624
            sse_fn_epp = sse_op_table5[val];
4625
            if (!sse_fn_epp) {
4626
                goto illegal_op;
4627
            }
4628
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4629
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4630
            sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4631
            break;
4632
        case 0x70: /* pshufx insn */
4633
        case 0xc6: /* pshufx insn */
4634
            val = cpu_ldub_code(env, s->pc++);
4635
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4636
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4637
            /* XXX: introduce a new table? */
4638
            sse_fn_ppi = (SSEFunc_0_ppi)sse_fn_epp;
4639
            sse_fn_ppi(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4640
            break;
4641
        case 0xc2:
4642
            /* compare insns */
4643
            val = cpu_ldub_code(env, s->pc++);
4644
            if (val >= 8)
4645
                goto illegal_op;
4646
            sse_fn_epp = sse_op_table4[val][b1];
4647

    
4648
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4649
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4650
            sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4651
            break;
4652
        case 0xf7:
4653
            /* maskmov : we must prepare A0 */
4654
            if (mod != 3)
4655
                goto illegal_op;
4656
#ifdef TARGET_X86_64
4657
            if (s->aflag == 2) {
4658
                gen_op_movq_A0_reg(R_EDI);
4659
            } else
4660
#endif
4661
            {
4662
                gen_op_movl_A0_reg(R_EDI);
4663
                if (s->aflag == 0)
4664
                    gen_op_andl_A0_ffff();
4665
            }
4666
            gen_add_A0_ds_seg(s);
4667

    
4668
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4669
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4670
            /* XXX: introduce a new table? */
4671
            sse_fn_eppt = (SSEFunc_0_eppt)sse_fn_epp;
4672
            sse_fn_eppt(cpu_env, cpu_ptr0, cpu_ptr1, cpu_A0);
4673
            break;
4674
        default:
4675
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4676
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4677
            sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4678
            break;
4679
        }
4680
        if (b == 0x2e || b == 0x2f) {
4681
            set_cc_op(s, CC_OP_EFLAGS);
4682
        }
4683
    }
4684
}
4685

    
4686
/* convert one instruction. s->is_jmp is set if the translation must
4687
   be stopped. Return the next pc value */
4688
static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
4689
                               target_ulong pc_start)
4690
{
4691
    int b, prefixes, aflag, dflag;
4692
    int shift, ot;
4693
    int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
4694
    target_ulong next_eip, tval;
4695
    int rex_w, rex_r;
4696

    
4697
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
4698
        tcg_gen_debug_insn_start(pc_start);
4699
    }
4700
    s->pc = pc_start;
4701
    prefixes = 0;
4702
    aflag = s->code32;
4703
    dflag = s->code32;
4704
    s->override = -1;
4705
    rex_w = -1;
4706
    rex_r = 0;
4707
#ifdef TARGET_X86_64
4708
    s->rex_x = 0;
4709
    s->rex_b = 0;
4710
    x86_64_hregs = 0;
4711
#endif
4712
    s->rip_offset = 0; /* for relative ip address */
4713
    s->vex_l = 0;
4714
    s->vex_v = 0;
4715
 next_byte:
4716
    b = cpu_ldub_code(env, s->pc);
4717
    s->pc++;
4718
    /* Collect prefixes.  */
4719
    switch (b) {
4720
    case 0xf3:
4721
        prefixes |= PREFIX_REPZ;
4722
        goto next_byte;
4723
    case 0xf2:
4724
        prefixes |= PREFIX_REPNZ;
4725
        goto next_byte;
4726
    case 0xf0:
4727
        prefixes |= PREFIX_LOCK;
4728
        goto next_byte;
4729
    case 0x2e:
4730
        s->override = R_CS;
4731
        goto next_byte;
4732
    case 0x36:
4733
        s->override = R_SS;
4734
        goto next_byte;
4735
    case 0x3e:
4736
        s->override = R_DS;
4737
        goto next_byte;
4738
    case 0x26:
4739
        s->override = R_ES;
4740
        goto next_byte;
4741
    case 0x64:
4742
        s->override = R_FS;
4743
        goto next_byte;
4744
    case 0x65:
4745
        s->override = R_GS;
4746
        goto next_byte;
4747
    case 0x66:
4748
        prefixes |= PREFIX_DATA;
4749
        goto next_byte;
4750
    case 0x67:
4751
        prefixes |= PREFIX_ADR;
4752
        goto next_byte;
4753
#ifdef TARGET_X86_64
4754
    case 0x40 ... 0x4f:
4755
        if (CODE64(s)) {
4756
            /* REX prefix */
4757
            rex_w = (b >> 3) & 1;
4758
            rex_r = (b & 0x4) << 1;
4759
            s->rex_x = (b & 0x2) << 2;
4760
            REX_B(s) = (b & 0x1) << 3;
4761
            x86_64_hregs = 1; /* select uniform byte register addressing */
4762
            goto next_byte;
4763
        }
4764
        break;
4765
#endif
4766
    case 0xc5: /* 2-byte VEX */
4767
    case 0xc4: /* 3-byte VEX */
4768
        /* VEX prefixes cannot be used except in 32-bit mode.
4769
           Otherwise the instruction is LES or LDS.  */
4770
        if (s->code32 && !s->vm86) {
4771
            static const int pp_prefix[4] = {
4772
                0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ
4773
            };
4774
            int vex3, vex2 = cpu_ldub_code(env, s->pc);
4775

    
4776
            if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
4777
                /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4778
                   otherwise the instruction is LES or LDS.  */
4779
                break;
4780
            }
4781
            s->pc++;
4782

    
4783
            /* 4.1.1-4.1.3: No preceeding lock, 66, f2, f3, or rex prefixes. */
4784
            if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ
4785
                            | PREFIX_LOCK | PREFIX_DATA)) {
4786
                goto illegal_op;
4787
            }
4788
#ifdef TARGET_X86_64
4789
            if (x86_64_hregs) {
4790
                goto illegal_op;
4791
            }
4792
#endif
4793
            rex_r = (~vex2 >> 4) & 8;
4794
            if (b == 0xc5) {
4795
                vex3 = vex2;
4796
                b = cpu_ldub_code(env, s->pc++);
4797
            } else {
4798
#ifdef TARGET_X86_64
4799
                s->rex_x = (~vex2 >> 3) & 8;
4800
                s->rex_b = (~vex2 >> 2) & 8;
4801
#endif
4802
                vex3 = cpu_ldub_code(env, s->pc++);
4803
                rex_w = (vex3 >> 7) & 1;
4804
                switch (vex2 & 0x1f) {
4805
                case 0x01: /* Implied 0f leading opcode bytes.  */
4806
                    b = cpu_ldub_code(env, s->pc++) | 0x100;
4807
                    break;
4808
                case 0x02: /* Implied 0f 38 leading opcode bytes.  */
4809
                    b = 0x138;
4810
                    break;
4811
                case 0x03: /* Implied 0f 3a leading opcode bytes.  */
4812
                    b = 0x13a;
4813
                    break;
4814
                default:   /* Reserved for future use.  */
4815
                    goto illegal_op;
4816
                }
4817
            }
4818
            s->vex_v = (~vex3 >> 3) & 0xf;
4819
            s->vex_l = (vex3 >> 2) & 1;
4820
            prefixes |= pp_prefix[vex3 & 3] | PREFIX_VEX;
4821
        }
4822
        break;
4823
    }
4824

    
4825
    /* Post-process prefixes.  */
4826
    if (prefixes & PREFIX_DATA) {
4827
        dflag ^= 1;
4828
    }
4829
    if (prefixes & PREFIX_ADR) {
4830
        aflag ^= 1;
4831
    }
4832
#ifdef TARGET_X86_64
4833
    if (CODE64(s)) {
4834
        if (rex_w == 1) {
4835
            /* 0x66 is ignored if rex.w is set */
4836
            dflag = 2;
4837
        }
4838
        if (!(prefixes & PREFIX_ADR)) {
4839
            aflag = 2;
4840
        }
4841
    }
4842
#endif
4843

    
4844
    s->prefix = prefixes;
4845
    s->aflag = aflag;
4846
    s->dflag = dflag;
4847

    
4848
    /* lock generation */
4849
    if (prefixes & PREFIX_LOCK)
4850
        gen_helper_lock();
4851

    
4852
    /* now check op code */
4853
 reswitch:
4854
    switch(b) {
4855
    case 0x0f:
4856
        /**************************/
4857
        /* extended op code */
4858
        b = cpu_ldub_code(env, s->pc++) | 0x100;
4859
        goto reswitch;
4860

    
4861
        /**************************/
4862
        /* arith & logic */
4863
    case 0x00 ... 0x05:
4864
    case 0x08 ... 0x0d:
4865
    case 0x10 ... 0x15:
4866
    case 0x18 ... 0x1d:
4867
    case 0x20 ... 0x25:
4868
    case 0x28 ... 0x2d:
4869
    case 0x30 ... 0x35:
4870
    case 0x38 ... 0x3d:
4871
        {
4872
            int op, f, val;
4873
            op = (b >> 3) & 7;
4874
            f = (b >> 1) & 3;
4875

    
4876
            if ((b & 1) == 0)
4877
                ot = OT_BYTE;
4878
            else
4879
                ot = dflag + OT_WORD;
4880

    
4881
            switch(f) {
4882
            case 0: /* OP Ev, Gv */
4883
                modrm = cpu_ldub_code(env, s->pc++);
4884
                reg = ((modrm >> 3) & 7) | rex_r;
4885
                mod = (modrm >> 6) & 3;
4886
                rm = (modrm & 7) | REX_B(s);
4887
                if (mod != 3) {
4888
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4889
                    opreg = OR_TMP0;
4890
                } else if (op == OP_XORL && rm == reg) {
4891
                xor_zero:
4892
                    /* xor reg, reg optimisation */
4893
                    gen_op_movl_T0_0();
4894
                    set_cc_op(s, CC_OP_LOGICB + ot);
4895
                    gen_op_mov_reg_T0(ot, reg);
4896
                    gen_op_update1_cc();
4897
                    break;
4898
                } else {
4899
                    opreg = rm;
4900
                }
4901
                gen_op_mov_TN_reg(ot, 1, reg);
4902
                gen_op(s, op, ot, opreg);
4903
                break;
4904
            case 1: /* OP Gv, Ev */
4905
                modrm = cpu_ldub_code(env, s->pc++);
4906
                mod = (modrm >> 6) & 3;
4907
                reg = ((modrm >> 3) & 7) | rex_r;
4908
                rm = (modrm & 7) | REX_B(s);
4909
                if (mod != 3) {
4910
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4911
                    gen_op_ld_T1_A0(ot + s->mem_index);
4912
                } else if (op == OP_XORL && rm == reg) {
4913
                    goto xor_zero;
4914
                } else {
4915
                    gen_op_mov_TN_reg(ot, 1, rm);
4916
                }
4917
                gen_op(s, op, ot, reg);
4918
                break;
4919
            case 2: /* OP A, Iv */
4920
                val = insn_get(env, s, ot);
4921
                gen_op_movl_T1_im(val);
4922
                gen_op(s, op, ot, OR_EAX);
4923
                break;
4924
            }
4925
        }
4926
        break;
4927

    
4928
    case 0x82:
4929
        if (CODE64(s))
4930
            goto illegal_op;
4931
    case 0x80: /* GRP1 */
4932
    case 0x81:
4933
    case 0x83:
4934
        {
4935
            int val;
4936

    
4937
            if ((b & 1) == 0)
4938
                ot = OT_BYTE;
4939
            else
4940
                ot = dflag + OT_WORD;
4941

    
4942
            modrm = cpu_ldub_code(env, s->pc++);
4943
            mod = (modrm >> 6) & 3;
4944
            rm = (modrm & 7) | REX_B(s);
4945
            op = (modrm >> 3) & 7;
4946

    
4947
            if (mod != 3) {
4948
                if (b == 0x83)
4949
                    s->rip_offset = 1;
4950
                else
4951
                    s->rip_offset = insn_const_size(ot);
4952
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4953
                opreg = OR_TMP0;
4954
            } else {
4955
                opreg = rm;
4956
            }
4957

    
4958
            switch(b) {
4959
            default:
4960
            case 0x80:
4961
            case 0x81:
4962
            case 0x82:
4963
                val = insn_get(env, s, ot);
4964
                break;
4965
            case 0x83:
4966
                val = (int8_t)insn_get(env, s, OT_BYTE);
4967
                break;
4968
            }
4969
            gen_op_movl_T1_im(val);
4970
            gen_op(s, op, ot, opreg);
4971
        }
4972
        break;
4973

    
4974
        /**************************/
4975
        /* inc, dec, and other misc arith */
4976
    case 0x40 ... 0x47: /* inc Gv */
4977
        ot = dflag ? OT_LONG : OT_WORD;
4978
        gen_inc(s, ot, OR_EAX + (b & 7), 1);
4979
        break;
4980
    case 0x48 ... 0x4f: /* dec Gv */
4981
        ot = dflag ? OT_LONG : OT_WORD;
4982
        gen_inc(s, ot, OR_EAX + (b & 7), -1);
4983
        break;
4984
    case 0xf6: /* GRP3 */
4985
    case 0xf7:
4986
        if ((b & 1) == 0)
4987
            ot = OT_BYTE;
4988
        else
4989
            ot = dflag + OT_WORD;
4990

    
4991
        modrm = cpu_ldub_code(env, s->pc++);
4992
        mod = (modrm >> 6) & 3;
4993
        rm = (modrm & 7) | REX_B(s);
4994
        op = (modrm >> 3) & 7;
4995
        if (mod != 3) {
4996
            if (op == 0)
4997
                s->rip_offset = insn_const_size(ot);
4998
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4999
            gen_op_ld_T0_A0(ot + s->mem_index);
5000
        } else {
5001
            gen_op_mov_TN_reg(ot, 0, rm);
5002
        }
5003

    
5004
        switch(op) {
5005
        case 0: /* test */
5006
            val = insn_get(env, s, ot);
5007
            gen_op_movl_T1_im(val);
5008
            gen_op_testl_T0_T1_cc();
5009
            set_cc_op(s, CC_OP_LOGICB + ot);
5010
            break;
5011
        case 2: /* not */
5012
            tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
5013
            if (mod != 3) {
5014
                gen_op_st_T0_A0(ot + s->mem_index);
5015
            } else {
5016
                gen_op_mov_reg_T0(ot, rm);
5017
            }
5018
            break;
5019
        case 3: /* neg */
5020
            tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
5021
            if (mod != 3) {
5022
                gen_op_st_T0_A0(ot + s->mem_index);
5023
            } else {
5024
                gen_op_mov_reg_T0(ot, rm);
5025
            }
5026
            gen_op_update_neg_cc();
5027
            set_cc_op(s, CC_OP_SUBB + ot);
5028
            break;
5029
        case 4: /* mul */
5030
            switch(ot) {
5031
            case OT_BYTE:
5032
                gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX);
5033
                tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
5034
                tcg_gen_ext8u_tl(cpu_T[1], cpu_T[1]);
5035
                /* XXX: use 32 bit mul which could be faster */
5036
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
5037
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
5038
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
5039
                tcg_gen_andi_tl(cpu_cc_src, cpu_T[0], 0xff00);
5040
                set_cc_op(s, CC_OP_MULB);
5041
                break;
5042
            case OT_WORD:
5043
                gen_op_mov_TN_reg(OT_WORD, 1, R_EAX);
5044
                tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
5045
                tcg_gen_ext16u_tl(cpu_T[1], cpu_T[1]);
5046
                /* XXX: use 32 bit mul which could be faster */
5047
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
5048
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
5049
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
5050
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
5051
                gen_op_mov_reg_T0(OT_WORD, R_EDX);
5052
                tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
5053
                set_cc_op(s, CC_OP_MULW);
5054
                break;
5055
            default:
5056
            case OT_LONG:
5057
#ifdef TARGET_X86_64
5058
                gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
5059
                tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
5060
                tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
5061
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
5062
                gen_op_mov_reg_T0(OT_LONG, R_EAX);
5063
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
5064
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
5065
                gen_op_mov_reg_T0(OT_LONG, R_EDX);
5066
                tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
5067
#else
5068
                {
5069
                    TCGv_i64 t0, t1;
5070
                    t0 = tcg_temp_new_i64();
5071
                    t1 = tcg_temp_new_i64();
5072
                    gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
5073
                    tcg_gen_extu_i32_i64(t0, cpu_T[0]);
5074
                    tcg_gen_extu_i32_i64(t1, cpu_T[1]);
5075
                    tcg_gen_mul_i64(t0, t0, t1);
5076
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
5077
                    gen_op_mov_reg_T0(OT_LONG, R_EAX);
5078
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
5079
                    tcg_gen_shri_i64(t0, t0, 32);
5080
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
5081
                    gen_op_mov_reg_T0(OT_LONG, R_EDX);
5082
                    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
5083
                }
5084
#endif
5085
                set_cc_op(s, CC_OP_MULL);
5086
                break;
5087
#ifdef TARGET_X86_64
5088
            case OT_QUAD:
5089
                gen_helper_mulq_EAX_T0(cpu_env, cpu_T[0]);
5090
                set_cc_op(s, CC_OP_MULQ);
5091
                break;
5092
#endif
5093
            }
5094
            break;
5095
        case 5: /* imul */
5096
            switch(ot) {
5097
            case OT_BYTE:
5098
                gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX);
5099
                tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
5100
                tcg_gen_ext8s_tl(cpu_T[1], cpu_T[1]);
5101
                /* XXX: use 32 bit mul which could be faster */
5102
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
5103
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
5104
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
5105
                tcg_gen_ext8s_tl(cpu_tmp0, cpu_T[0]);
5106
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
5107
                set_cc_op(s, CC_OP_MULB);
5108
                break;
5109
            case OT_WORD:
5110
                gen_op_mov_TN_reg(OT_WORD, 1, R_EAX);
5111
                tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
5112
                tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
5113
                /* XXX: use 32 bit mul which could be faster */
5114
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
5115
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
5116
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
5117
                tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
5118
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
5119
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
5120
                gen_op_mov_reg_T0(OT_WORD, R_EDX);
5121
                set_cc_op(s, CC_OP_MULW);
5122
                break;
5123
            default:
5124
            case OT_LONG:
5125
#ifdef TARGET_X86_64
5126
                gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
5127
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
5128
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
5129
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
5130
                gen_op_mov_reg_T0(OT_LONG, R_EAX);
5131
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
5132
                tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
5133
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
5134
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
5135
                gen_op_mov_reg_T0(OT_LONG, R_EDX);
5136
#else
5137
                {
5138
                    TCGv_i64 t0, t1;
5139
                    t0 = tcg_temp_new_i64();
5140
                    t1 = tcg_temp_new_i64();
5141
                    gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
5142
                    tcg_gen_ext_i32_i64(t0, cpu_T[0]);
5143
                    tcg_gen_ext_i32_i64(t1, cpu_T[1]);
5144
                    tcg_gen_mul_i64(t0, t0, t1);
5145
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
5146
                    gen_op_mov_reg_T0(OT_LONG, R_EAX);
5147
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
5148
                    tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
5149
                    tcg_gen_shri_i64(t0, t0, 32);
5150
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
5151
                    gen_op_mov_reg_T0(OT_LONG, R_EDX);
5152
                    tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
5153
                }
5154
#endif
5155
                set_cc_op(s, CC_OP_MULL);
5156
                break;
5157
#ifdef TARGET_X86_64
5158
            case OT_QUAD:
5159
                gen_helper_imulq_EAX_T0(cpu_env, cpu_T[0]);
5160
                set_cc_op(s, CC_OP_MULQ);
5161
                break;
5162
#endif
5163
            }
5164
            break;
5165
        case 6: /* div */
5166
            switch(ot) {
5167
            case OT_BYTE:
5168
                gen_jmp_im(pc_start - s->cs_base);
5169
                gen_helper_divb_AL(cpu_env, cpu_T[0]);
5170
                break;
5171
            case OT_WORD:
5172
                gen_jmp_im(pc_start - s->cs_base);
5173
                gen_helper_divw_AX(cpu_env, cpu_T[0]);
5174
                break;
5175
            default:
5176
            case OT_LONG:
5177
                gen_jmp_im(pc_start - s->cs_base);
5178
                gen_helper_divl_EAX(cpu_env, cpu_T[0]);
5179
                break;
5180
#ifdef TARGET_X86_64
5181
            case OT_QUAD:
5182
                gen_jmp_im(pc_start - s->cs_base);
5183
                gen_helper_divq_EAX(cpu_env, cpu_T[0]);
5184
                break;
5185
#endif
5186
            }
5187
            break;
5188
        case 7: /* idiv */
5189
            switch(ot) {
5190
            case OT_BYTE:
5191
                gen_jmp_im(pc_start - s->cs_base);
5192
                gen_helper_idivb_AL(cpu_env, cpu_T[0]);
5193
                break;
5194
            case OT_WORD:
5195
                gen_jmp_im(pc_start - s->cs_base);
5196
                gen_helper_idivw_AX(cpu_env, cpu_T[0]);
5197
                break;
5198
            default:
5199
            case OT_LONG:
5200
                gen_jmp_im(pc_start - s->cs_base);
5201
                gen_helper_idivl_EAX(cpu_env, cpu_T[0]);
5202
                break;
5203
#ifdef TARGET_X86_64
5204
            case OT_QUAD:
5205
                gen_jmp_im(pc_start - s->cs_base);
5206
                gen_helper_idivq_EAX(cpu_env, cpu_T[0]);
5207
                break;
5208
#endif
5209
            }
5210
            break;
5211
        default:
5212
            goto illegal_op;
5213
        }
5214
        break;
5215

    
5216
    case 0xfe: /* GRP4 */
5217
    case 0xff: /* GRP5 */
5218
        if ((b & 1) == 0)
5219
            ot = OT_BYTE;
5220
        else
5221
            ot = dflag + OT_WORD;
5222

    
5223
        modrm = cpu_ldub_code(env, s->pc++);
5224
        mod = (modrm >> 6) & 3;
5225
        rm = (modrm & 7) | REX_B(s);
5226
        op = (modrm >> 3) & 7;
5227
        if (op >= 2 && b == 0xfe) {
5228
            goto illegal_op;
5229
        }
5230
        if (CODE64(s)) {
5231
            if (op == 2 || op == 4) {
5232
                /* operand size for jumps is 64 bit */
5233
                ot = OT_QUAD;
5234
            } else if (op == 3 || op == 5) {
5235
                ot = dflag ? OT_LONG + (rex_w == 1) : OT_WORD;
5236
            } else if (op == 6) {
5237
                /* default push size is 64 bit */
5238
                ot = dflag ? OT_QUAD : OT_WORD;
5239
            }
5240
        }
5241
        if (mod != 3) {
5242
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5243
            if (op >= 2 && op != 3 && op != 5)
5244
                gen_op_ld_T0_A0(ot + s->mem_index);
5245
        } else {
5246
            gen_op_mov_TN_reg(ot, 0, rm);
5247
        }
5248

    
5249
        switch(op) {
5250
        case 0: /* inc Ev */
5251
            if (mod != 3)
5252
                opreg = OR_TMP0;
5253
            else
5254
                opreg = rm;
5255
            gen_inc(s, ot, opreg, 1);
5256
            break;
5257
        case 1: /* dec Ev */
5258
            if (mod != 3)
5259
                opreg = OR_TMP0;
5260
            else
5261
                opreg = rm;
5262
            gen_inc(s, ot, opreg, -1);
5263
            break;
5264
        case 2: /* call Ev */
5265
            /* XXX: optimize if memory (no 'and' is necessary) */
5266
            if (s->dflag == 0)
5267
                gen_op_andl_T0_ffff();
5268
            next_eip = s->pc - s->cs_base;
5269
            gen_movtl_T1_im(next_eip);
5270
            gen_push_T1(s);
5271
            gen_op_jmp_T0();
5272
            gen_eob(s);
5273
            break;
5274
        case 3: /* lcall Ev */
5275
            gen_op_ld_T1_A0(ot + s->mem_index);
5276
            gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
5277
            gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
5278
        do_lcall:
5279
            if (s->pe && !s->vm86) {
5280
                gen_update_cc_op(s);
5281
                gen_jmp_im(pc_start - s->cs_base);
5282
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5283
                gen_helper_lcall_protected(cpu_env, cpu_tmp2_i32, cpu_T[1],
5284
                                           tcg_const_i32(dflag),
5285
                                           tcg_const_i32(s->pc - pc_start));
5286
            } else {
5287
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5288
                gen_helper_lcall_real(cpu_env, cpu_tmp2_i32, cpu_T[1],
5289
                                      tcg_const_i32(dflag),
5290
                                      tcg_const_i32(s->pc - s->cs_base));
5291
            }
5292
            gen_eob(s);
5293
            break;
5294
        case 4: /* jmp Ev */
5295
            if (s->dflag == 0)
5296
                gen_op_andl_T0_ffff();
5297
            gen_op_jmp_T0();
5298
            gen_eob(s);
5299
            break;
5300
        case 5: /* ljmp Ev */
5301
            gen_op_ld_T1_A0(ot + s->mem_index);
5302
            gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
5303
            gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
5304
        do_ljmp:
5305
            if (s->pe && !s->vm86) {
5306
                gen_update_cc_op(s);
5307
                gen_jmp_im(pc_start - s->cs_base);
5308
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5309
                gen_helper_ljmp_protected(cpu_env, cpu_tmp2_i32, cpu_T[1],
5310
                                          tcg_const_i32(s->pc - pc_start));
5311
            } else {
5312
                gen_op_movl_seg_T0_vm(R_CS);
5313
                gen_op_movl_T0_T1();
5314
                gen_op_jmp_T0();
5315
            }
5316
            gen_eob(s);
5317
            break;
5318
        case 6: /* push Ev */
5319
            gen_push_T0(s);
5320
            break;
5321
        default:
5322
            goto illegal_op;
5323
        }
5324
        break;
5325

    
5326
    case 0x84: /* test Ev, Gv */
5327
    case 0x85:
5328
        if ((b & 1) == 0)
5329
            ot = OT_BYTE;
5330
        else
5331
            ot = dflag + OT_WORD;
5332

    
5333
        modrm = cpu_ldub_code(env, s->pc++);
5334
        reg = ((modrm >> 3) & 7) | rex_r;
5335

    
5336
        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5337
        gen_op_mov_TN_reg(ot, 1, reg);
5338
        gen_op_testl_T0_T1_cc();
5339
        set_cc_op(s, CC_OP_LOGICB + ot);
5340
        break;
5341

    
5342
    case 0xa8: /* test eAX, Iv */
5343
    case 0xa9:
5344
        if ((b & 1) == 0)
5345
            ot = OT_BYTE;
5346
        else
5347
            ot = dflag + OT_WORD;
5348
        val = insn_get(env, s, ot);
5349

    
5350
        gen_op_mov_TN_reg(ot, 0, OR_EAX);
5351
        gen_op_movl_T1_im(val);
5352
        gen_op_testl_T0_T1_cc();
5353
        set_cc_op(s, CC_OP_LOGICB + ot);
5354
        break;
5355

    
5356
    case 0x98: /* CWDE/CBW */
5357
#ifdef TARGET_X86_64
5358
        if (dflag == 2) {
5359
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
5360
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
5361
            gen_op_mov_reg_T0(OT_QUAD, R_EAX);
5362
        } else
5363
#endif
5364
        if (dflag == 1) {
5365
            gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
5366
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
5367
            gen_op_mov_reg_T0(OT_LONG, R_EAX);
5368
        } else {
5369
            gen_op_mov_TN_reg(OT_BYTE, 0, R_EAX);
5370
            tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
5371
            gen_op_mov_reg_T0(OT_WORD, R_EAX);
5372
        }
5373
        break;
5374
    case 0x99: /* CDQ/CWD */
5375
#ifdef TARGET_X86_64
5376
        if (dflag == 2) {
5377
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
5378
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 63);
5379
            gen_op_mov_reg_T0(OT_QUAD, R_EDX);
5380
        } else
5381
#endif
5382
        if (dflag == 1) {
5383
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
5384
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
5385
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 31);
5386
            gen_op_mov_reg_T0(OT_LONG, R_EDX);
5387
        } else {
5388
            gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
5389
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
5390
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 15);
5391
            gen_op_mov_reg_T0(OT_WORD, R_EDX);
5392
        }
5393
        break;
5394
    case 0x1af: /* imul Gv, Ev */
5395
    case 0x69: /* imul Gv, Ev, I */
5396
    case 0x6b:
5397
        ot = dflag + OT_WORD;
5398
        modrm = cpu_ldub_code(env, s->pc++);
5399
        reg = ((modrm >> 3) & 7) | rex_r;
5400
        if (b == 0x69)
5401
            s->rip_offset = insn_const_size(ot);
5402
        else if (b == 0x6b)
5403
            s->rip_offset = 1;
5404
        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5405
        if (b == 0x69) {
5406
            val = insn_get(env, s, ot);
5407
            gen_op_movl_T1_im(val);
5408
        } else if (b == 0x6b) {
5409
            val = (int8_t)insn_get(env, s, OT_BYTE);
5410
            gen_op_movl_T1_im(val);
5411
        } else {
5412
            gen_op_mov_TN_reg(ot, 1, reg);
5413
        }
5414

    
5415
#ifdef TARGET_X86_64
5416
        if (ot == OT_QUAD) {
5417
            gen_helper_imulq_T0_T1(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
5418
        } else
5419
#endif
5420
        if (ot == OT_LONG) {
5421
#ifdef TARGET_X86_64
5422
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
5423
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
5424
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
5425
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
5426
                tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
5427
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
5428
#else
5429
                {
5430
                    TCGv_i64 t0, t1;
5431
                    t0 = tcg_temp_new_i64();
5432
                    t1 = tcg_temp_new_i64();
5433
                    tcg_gen_ext_i32_i64(t0, cpu_T[0]);
5434
                    tcg_gen_ext_i32_i64(t1, cpu_T[1]);
5435
                    tcg_gen_mul_i64(t0, t0, t1);
5436
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
5437
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
5438
                    tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
5439
                    tcg_gen_shri_i64(t0, t0, 32);
5440
                    tcg_gen_trunc_i64_i32(cpu_T[1], t0);
5441
                    tcg_gen_sub_tl(cpu_cc_src, cpu_T[1], cpu_tmp0);
5442
                }
5443
#endif
5444
        } else {
5445
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
5446
            tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
5447
            /* XXX: use 32 bit mul which could be faster */
5448
            tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
5449
            tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
5450
            tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
5451
            tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
5452
        }
5453
        gen_op_mov_reg_T0(ot, reg);
5454
        set_cc_op(s, CC_OP_MULB + ot);
5455
        break;
5456
    case 0x1c0:
5457
    case 0x1c1: /* xadd Ev, Gv */
5458
        if ((b & 1) == 0)
5459
            ot = OT_BYTE;
5460
        else
5461
            ot = dflag + OT_WORD;
5462
        modrm = cpu_ldub_code(env, s->pc++);
5463
        reg = ((modrm >> 3) & 7) | rex_r;
5464
        mod = (modrm >> 6) & 3;
5465
        if (mod == 3) {
5466
            rm = (modrm & 7) | REX_B(s);
5467
            gen_op_mov_TN_reg(ot, 0, reg);
5468
            gen_op_mov_TN_reg(ot, 1, rm);
5469
            gen_op_addl_T0_T1();
5470
            gen_op_mov_reg_T1(ot, reg);
5471
            gen_op_mov_reg_T0(ot, rm);
5472
        } else {
5473
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5474
            gen_op_mov_TN_reg(ot, 0, reg);
5475
            gen_op_ld_T1_A0(ot + s->mem_index);
5476
            gen_op_addl_T0_T1();
5477
            gen_op_st_T0_A0(ot + s->mem_index);
5478
            gen_op_mov_reg_T1(ot, reg);
5479
        }
5480
        gen_op_update2_cc();
5481
        set_cc_op(s, CC_OP_ADDB + ot);
5482
        break;
5483
    case 0x1b0:
5484
    case 0x1b1: /* cmpxchg Ev, Gv */
5485
        {
5486
            int label1, label2;
5487
            TCGv t0, t1, t2, a0;
5488

    
5489
            if ((b & 1) == 0)
5490
                ot = OT_BYTE;
5491
            else
5492
                ot = dflag + OT_WORD;
5493
            modrm = cpu_ldub_code(env, s->pc++);
5494
            reg = ((modrm >> 3) & 7) | rex_r;
5495
            mod = (modrm >> 6) & 3;
5496
            t0 = tcg_temp_local_new();
5497
            t1 = tcg_temp_local_new();
5498
            t2 = tcg_temp_local_new();
5499
            a0 = tcg_temp_local_new();
5500
            gen_op_mov_v_reg(ot, t1, reg);
5501
            if (mod == 3) {
5502
                rm = (modrm & 7) | REX_B(s);
5503
                gen_op_mov_v_reg(ot, t0, rm);
5504
            } else {
5505
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5506
                tcg_gen_mov_tl(a0, cpu_A0);
5507
                gen_op_ld_v(ot + s->mem_index, t0, a0);
5508
                rm = 0; /* avoid warning */
5509
            }
5510
            label1 = gen_new_label();
5511
            tcg_gen_mov_tl(t2, cpu_regs[R_EAX]);
5512
            gen_extu(ot, t0);
5513
            gen_extu(ot, t2);
5514
            tcg_gen_brcond_tl(TCG_COND_EQ, t2, t0, label1);
5515
            label2 = gen_new_label();
5516
            if (mod == 3) {
5517
                gen_op_mov_reg_v(ot, R_EAX, t0);
5518
                tcg_gen_br(label2);
5519
                gen_set_label(label1);
5520
                gen_op_mov_reg_v(ot, rm, t1);
5521
            } else {
5522
                /* perform no-op store cycle like physical cpu; must be
5523
                   before changing accumulator to ensure idempotency if
5524
                   the store faults and the instruction is restarted */
5525
                gen_op_st_v(ot + s->mem_index, t0, a0);
5526
                gen_op_mov_reg_v(ot, R_EAX, t0);
5527
                tcg_gen_br(label2);
5528
                gen_set_label(label1);
5529
                gen_op_st_v(ot + s->mem_index, t1, a0);
5530
            }
5531
            gen_set_label(label2);
5532
            tcg_gen_mov_tl(cpu_cc_src, t0);
5533
            tcg_gen_mov_tl(cpu_cc_srcT, t2);
5534
            tcg_gen_sub_tl(cpu_cc_dst, t2, t0);
5535
            set_cc_op(s, CC_OP_SUBB + ot);
5536
            tcg_temp_free(t0);
5537
            tcg_temp_free(t1);
5538
            tcg_temp_free(t2);
5539
            tcg_temp_free(a0);
5540
        }
5541
        break;
5542
    case 0x1c7: /* cmpxchg8b */
5543
        modrm = cpu_ldub_code(env, s->pc++);
5544
        mod = (modrm >> 6) & 3;
5545
        if ((mod == 3) || ((modrm & 0x38) != 0x8))
5546
            goto illegal_op;
5547
#ifdef TARGET_X86_64
5548
        if (dflag == 2) {
5549
            if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
5550
                goto illegal_op;
5551
            gen_jmp_im(pc_start - s->cs_base);
5552
            gen_update_cc_op(s);
5553
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5554
            gen_helper_cmpxchg16b(cpu_env, cpu_A0);
5555
        } else
5556
#endif        
5557
        {
5558
            if (!(s->cpuid_features & CPUID_CX8))
5559
                goto illegal_op;
5560
            gen_jmp_im(pc_start - s->cs_base);
5561
            gen_update_cc_op(s);
5562
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5563
            gen_helper_cmpxchg8b(cpu_env, cpu_A0);
5564
        }
5565
        set_cc_op(s, CC_OP_EFLAGS);
5566
        break;
5567

    
5568
        /**************************/
5569
        /* push/pop */
5570
    case 0x50 ... 0x57: /* push */
5571
        gen_op_mov_TN_reg(OT_LONG, 0, (b & 7) | REX_B(s));
5572
        gen_push_T0(s);
5573
        break;
5574
    case 0x58 ... 0x5f: /* pop */
5575
        if (CODE64(s)) {
5576
            ot = dflag ? OT_QUAD : OT_WORD;
5577
        } else {
5578
            ot = dflag + OT_WORD;
5579
        }
5580
        gen_pop_T0(s);
5581
        /* NOTE: order is important for pop %sp */
5582
        gen_pop_update(s);
5583
        gen_op_mov_reg_T0(ot, (b & 7) | REX_B(s));
5584
        break;
5585
    case 0x60: /* pusha */
5586
        if (CODE64(s))
5587
            goto illegal_op;
5588
        gen_pusha(s);
5589
        break;
5590
    case 0x61: /* popa */
5591
        if (CODE64(s))
5592
            goto illegal_op;
5593
        gen_popa(s);
5594
        break;
5595
    case 0x68: /* push Iv */
5596
    case 0x6a:
5597
        if (CODE64(s)) {
5598
            ot = dflag ? OT_QUAD : OT_WORD;
5599
        } else {
5600
            ot = dflag + OT_WORD;
5601
        }
5602
        if (b == 0x68)
5603
            val = insn_get(env, s, ot);
5604
        else
5605
            val = (int8_t)insn_get(env, s, OT_BYTE);
5606
        gen_op_movl_T0_im(val);
5607
        gen_push_T0(s);
5608
        break;
5609
    case 0x8f: /* pop Ev */
5610
        if (CODE64(s)) {
5611
            ot = dflag ? OT_QUAD : OT_WORD;
5612
        } else {
5613
            ot = dflag + OT_WORD;
5614
        }
5615
        modrm = cpu_ldub_code(env, s->pc++);
5616
        mod = (modrm >> 6) & 3;
5617
        gen_pop_T0(s);
5618
        if (mod == 3) {
5619
            /* NOTE: order is important for pop %sp */
5620
            gen_pop_update(s);
5621
            rm = (modrm & 7) | REX_B(s);
5622
            gen_op_mov_reg_T0(ot, rm);
5623
        } else {
5624
            /* NOTE: order is important too for MMU exceptions */
5625
            s->popl_esp_hack = 1 << ot;
5626
            gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5627
            s->popl_esp_hack = 0;
5628
            gen_pop_update(s);
5629
        }
5630
        break;
5631
    case 0xc8: /* enter */
5632
        {
5633
            int level;
5634
            val = cpu_lduw_code(env, s->pc);
5635
            s->pc += 2;
5636
            level = cpu_ldub_code(env, s->pc++);
5637
            gen_enter(s, val, level);
5638
        }
5639
        break;
5640
    case 0xc9: /* leave */
5641
        /* XXX: exception not precise (ESP is updated before potential exception) */
5642
        if (CODE64(s)) {
5643
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EBP);
5644
            gen_op_mov_reg_T0(OT_QUAD, R_ESP);
5645
        } else if (s->ss32) {
5646
            gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
5647
            gen_op_mov_reg_T0(OT_LONG, R_ESP);
5648
        } else {
5649
            gen_op_mov_TN_reg(OT_WORD, 0, R_EBP);
5650
            gen_op_mov_reg_T0(OT_WORD, R_ESP);
5651
        }
5652
        gen_pop_T0(s);
5653
        if (CODE64(s)) {
5654
            ot = dflag ? OT_QUAD : OT_WORD;
5655
        } else {
5656
            ot = dflag + OT_WORD;
5657
        }
5658
        gen_op_mov_reg_T0(ot, R_EBP);
5659
        gen_pop_update(s);
5660
        break;
5661
    case 0x06: /* push es */
5662
    case 0x0e: /* push cs */
5663
    case 0x16: /* push ss */
5664
    case 0x1e: /* push ds */
5665
        if (CODE64(s))
5666
            goto illegal_op;
5667
        gen_op_movl_T0_seg(b >> 3);
5668
        gen_push_T0(s);
5669
        break;
5670
    case 0x1a0: /* push fs */
5671
    case 0x1a8: /* push gs */
5672
        gen_op_movl_T0_seg((b >> 3) & 7);
5673
        gen_push_T0(s);
5674
        break;
5675
    case 0x07: /* pop es */
5676
    case 0x17: /* pop ss */
5677
    case 0x1f: /* pop ds */
5678
        if (CODE64(s))
5679
            goto illegal_op;
5680
        reg = b >> 3;
5681
        gen_pop_T0(s);
5682
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
5683
        gen_pop_update(s);
5684
        if (reg == R_SS) {
5685
            /* if reg == SS, inhibit interrupts/trace. */
5686
            /* If several instructions disable interrupts, only the
5687
               _first_ does it */
5688
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
5689
                gen_helper_set_inhibit_irq(cpu_env);
5690
            s->tf = 0;
5691
        }
5692
        if (s->is_jmp) {
5693
            gen_jmp_im(s->pc - s->cs_base);
5694
            gen_eob(s);
5695
        }
5696
        break;
5697
    case 0x1a1: /* pop fs */
5698
    case 0x1a9: /* pop gs */
5699
        gen_pop_T0(s);
5700
        gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
5701
        gen_pop_update(s);
5702
        if (s->is_jmp) {
5703
            gen_jmp_im(s->pc - s->cs_base);
5704
            gen_eob(s);
5705
        }
5706
        break;
5707

    
5708
        /**************************/
5709
        /* mov */
5710
    case 0x88:
5711
    case 0x89: /* mov Gv, Ev */
5712
        if ((b & 1) == 0)
5713
            ot = OT_BYTE;
5714
        else
5715
            ot = dflag + OT_WORD;
5716
        modrm = cpu_ldub_code(env, s->pc++);
5717
        reg = ((modrm >> 3) & 7) | rex_r;
5718

    
5719
        /* generate a generic store */
5720
        gen_ldst_modrm(env, s, modrm, ot, reg, 1);
5721
        break;
5722
    case 0xc6:
5723
    case 0xc7: /* mov Ev, Iv */
5724
        if ((b & 1) == 0)
5725
            ot = OT_BYTE;
5726
        else
5727
            ot = dflag + OT_WORD;
5728
        modrm = cpu_ldub_code(env, s->pc++);
5729
        mod = (modrm >> 6) & 3;
5730
        if (mod != 3) {
5731
            s->rip_offset = insn_const_size(ot);
5732
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5733
        }
5734
        val = insn_get(env, s, ot);
5735
        gen_op_movl_T0_im(val);
5736
        if (mod != 3)
5737
            gen_op_st_T0_A0(ot + s->mem_index);
5738
        else
5739
            gen_op_mov_reg_T0(ot, (modrm & 7) | REX_B(s));
5740
        break;
5741
    case 0x8a:
5742
    case 0x8b: /* mov Ev, Gv */
5743
        if ((b & 1) == 0)
5744
            ot = OT_BYTE;
5745
        else
5746
            ot = OT_WORD + dflag;
5747
        modrm = cpu_ldub_code(env, s->pc++);
5748
        reg = ((modrm >> 3) & 7) | rex_r;
5749

    
5750
        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5751
        gen_op_mov_reg_T0(ot, reg);
5752
        break;
5753
    case 0x8e: /* mov seg, Gv */
5754
        modrm = cpu_ldub_code(env, s->pc++);
5755
        reg = (modrm >> 3) & 7;
5756
        if (reg >= 6 || reg == R_CS)
5757
            goto illegal_op;
5758
        gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
5759
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
5760
        if (reg == R_SS) {
5761
            /* if reg == SS, inhibit interrupts/trace */
5762
            /* If several instructions disable interrupts, only the
5763
               _first_ does it */
5764
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
5765
                gen_helper_set_inhibit_irq(cpu_env);
5766
            s->tf = 0;
5767
        }
5768
        if (s->is_jmp) {
5769
            gen_jmp_im(s->pc - s->cs_base);
5770
            gen_eob(s);
5771
        }
5772
        break;
5773
    case 0x8c: /* mov Gv, seg */
5774
        modrm = cpu_ldub_code(env, s->pc++);
5775
        reg = (modrm >> 3) & 7;
5776
        mod = (modrm >> 6) & 3;
5777
        if (reg >= 6)
5778
            goto illegal_op;
5779
        gen_op_movl_T0_seg(reg);
5780
        if (mod == 3)
5781
            ot = OT_WORD + dflag;
5782
        else
5783
            ot = OT_WORD;
5784
        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5785
        break;
5786

    
5787
    case 0x1b6: /* movzbS Gv, Eb */
5788
    case 0x1b7: /* movzwS Gv, Eb */
5789
    case 0x1be: /* movsbS Gv, Eb */
5790
    case 0x1bf: /* movswS Gv, Eb */
5791
        {
5792
            int d_ot;
5793
            /* d_ot is the size of destination */
5794
            d_ot = dflag + OT_WORD;
5795
            /* ot is the size of source */
5796
            ot = (b & 1) + OT_BYTE;
5797
            modrm = cpu_ldub_code(env, s->pc++);
5798
            reg = ((modrm >> 3) & 7) | rex_r;
5799
            mod = (modrm >> 6) & 3;
5800
            rm = (modrm & 7) | REX_B(s);
5801

    
5802
            if (mod == 3) {
5803
                gen_op_mov_TN_reg(ot, 0, rm);
5804
                switch(ot | (b & 8)) {
5805
                case OT_BYTE:
5806
                    tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
5807
                    break;
5808
                case OT_BYTE | 8:
5809
                    tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
5810
                    break;
5811
                case OT_WORD:
5812
                    tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
5813
                    break;
5814
                default:
5815
                case OT_WORD | 8:
5816
                    tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
5817
                    break;
5818
                }
5819
                gen_op_mov_reg_T0(d_ot, reg);
5820
            } else {
5821
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5822
                if (b & 8) {
5823
                    gen_op_lds_T0_A0(ot + s->mem_index);
5824
                } else {
5825
                    gen_op_ldu_T0_A0(ot + s->mem_index);
5826
                }
5827
                gen_op_mov_reg_T0(d_ot, reg);
5828
            }
5829
        }
5830
        break;
5831

    
5832
    case 0x8d: /* lea */
5833
        ot = dflag + OT_WORD;
5834
        modrm = cpu_ldub_code(env, s->pc++);
5835
        mod = (modrm >> 6) & 3;
5836
        if (mod == 3)
5837
            goto illegal_op;
5838
        reg = ((modrm >> 3) & 7) | rex_r;
5839
        /* we must ensure that no segment is added */
5840
        s->override = -1;
5841
        val = s->addseg;
5842
        s->addseg = 0;
5843
        gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5844
        s->addseg = val;
5845
        gen_op_mov_reg_A0(ot - OT_WORD, reg);
5846
        break;
5847

    
5848
    case 0xa0: /* mov EAX, Ov */
5849
    case 0xa1:
5850
    case 0xa2: /* mov Ov, EAX */
5851
    case 0xa3:
5852
        {
5853
            target_ulong offset_addr;
5854

    
5855
            if ((b & 1) == 0)
5856
                ot = OT_BYTE;
5857
            else
5858
                ot = dflag + OT_WORD;
5859
#ifdef TARGET_X86_64
5860
            if (s->aflag == 2) {
5861
                offset_addr = cpu_ldq_code(env, s->pc);
5862
                s->pc += 8;
5863
                gen_op_movq_A0_im(offset_addr);
5864
            } else
5865
#endif
5866
            {
5867
                if (s->aflag) {
5868
                    offset_addr = insn_get(env, s, OT_LONG);
5869
                } else {
5870
                    offset_addr = insn_get(env, s, OT_WORD);
5871
                }
5872
                gen_op_movl_A0_im(offset_addr);
5873
            }
5874
            gen_add_A0_ds_seg(s);
5875
            if ((b & 2) == 0) {
5876
                gen_op_ld_T0_A0(ot + s->mem_index);
5877
                gen_op_mov_reg_T0(ot, R_EAX);
5878
            } else {
5879
                gen_op_mov_TN_reg(ot, 0, R_EAX);
5880
                gen_op_st_T0_A0(ot + s->mem_index);
5881
            }
5882
        }
5883
        break;
5884
    case 0xd7: /* xlat */
5885
#ifdef TARGET_X86_64
5886
        if (s->aflag == 2) {
5887
            gen_op_movq_A0_reg(R_EBX);
5888
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
5889
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
5890
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
5891
        } else
5892
#endif
5893
        {
5894
            gen_op_movl_A0_reg(R_EBX);
5895
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
5896
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
5897
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
5898
            if (s->aflag == 0)
5899
                gen_op_andl_A0_ffff();
5900
            else
5901
                tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
5902
        }
5903
        gen_add_A0_ds_seg(s);
5904
        gen_op_ldu_T0_A0(OT_BYTE + s->mem_index);
5905
        gen_op_mov_reg_T0(OT_BYTE, R_EAX);
5906
        break;
5907
    case 0xb0 ... 0xb7: /* mov R, Ib */
5908
        val = insn_get(env, s, OT_BYTE);
5909
        gen_op_movl_T0_im(val);
5910
        gen_op_mov_reg_T0(OT_BYTE, (b & 7) | REX_B(s));
5911
        break;
5912
    case 0xb8 ... 0xbf: /* mov R, Iv */
5913
#ifdef TARGET_X86_64
5914
        if (dflag == 2) {
5915
            uint64_t tmp;
5916
            /* 64 bit case */
5917
            tmp = cpu_ldq_code(env, s->pc);
5918
            s->pc += 8;
5919
            reg = (b & 7) | REX_B(s);
5920
            gen_movtl_T0_im(tmp);
5921
            gen_op_mov_reg_T0(OT_QUAD, reg);
5922
        } else
5923
#endif
5924
        {
5925
            ot = dflag ? OT_LONG : OT_WORD;
5926
            val = insn_get(env, s, ot);
5927
            reg = (b & 7) | REX_B(s);
5928
            gen_op_movl_T0_im(val);
5929
            gen_op_mov_reg_T0(ot, reg);
5930
        }
5931
        break;
5932

    
5933
    case 0x91 ... 0x97: /* xchg R, EAX */
5934
    do_xchg_reg_eax:
5935
        ot = dflag + OT_WORD;
5936
        reg = (b & 7) | REX_B(s);
5937
        rm = R_EAX;
5938
        goto do_xchg_reg;
5939
    case 0x86:
5940
    case 0x87: /* xchg Ev, Gv */
5941
        if ((b & 1) == 0)
5942
            ot = OT_BYTE;
5943
        else
5944
            ot = dflag + OT_WORD;
5945
        modrm = cpu_ldub_code(env, s->pc++);
5946
        reg = ((modrm >> 3) & 7) | rex_r;
5947
        mod = (modrm >> 6) & 3;
5948
        if (mod == 3) {
5949
            rm = (modrm & 7) | REX_B(s);
5950
        do_xchg_reg:
5951
            gen_op_mov_TN_reg(ot, 0, reg);
5952
            gen_op_mov_TN_reg(ot, 1, rm);
5953
            gen_op_mov_reg_T0(ot, rm);
5954
            gen_op_mov_reg_T1(ot, reg);
5955
        } else {
5956
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5957
            gen_op_mov_TN_reg(ot, 0, reg);
5958
            /* for xchg, lock is implicit */
5959
            if (!(prefixes & PREFIX_LOCK))
5960
                gen_helper_lock();
5961
            gen_op_ld_T1_A0(ot + s->mem_index);
5962
            gen_op_st_T0_A0(ot + s->mem_index);
5963
            if (!(prefixes & PREFIX_LOCK))
5964
                gen_helper_unlock();
5965
            gen_op_mov_reg_T1(ot, reg);
5966
        }
5967
        break;
5968
    case 0xc4: /* les Gv */
5969
        /* In CODE64 this is VEX3; see above.  */
5970
        op = R_ES;
5971
        goto do_lxx;
5972
    case 0xc5: /* lds Gv */
5973
        /* In CODE64 this is VEX2; see above.  */
5974
        op = R_DS;
5975
        goto do_lxx;
5976
    case 0x1b2: /* lss Gv */
5977
        op = R_SS;
5978
        goto do_lxx;
5979
    case 0x1b4: /* lfs Gv */
5980
        op = R_FS;
5981
        goto do_lxx;
5982
    case 0x1b5: /* lgs Gv */
5983
        op = R_GS;
5984
    do_lxx:
5985
        ot = dflag ? OT_LONG : OT_WORD;
5986
        modrm = cpu_ldub_code(env, s->pc++);
5987
        reg = ((modrm >> 3) & 7) | rex_r;
5988
        mod = (modrm >> 6) & 3;
5989
        if (mod == 3)
5990
            goto illegal_op;
5991
        gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5992
        gen_op_ld_T1_A0(ot + s->mem_index);
5993
        gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
5994
        /* load the segment first to handle exceptions properly */
5995
        gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
5996
        gen_movl_seg_T0(s, op, pc_start - s->cs_base);
5997
        /* then put the data */
5998
        gen_op_mov_reg_T1(ot, reg);
5999
        if (s->is_jmp) {
6000
            gen_jmp_im(s->pc - s->cs_base);
6001
            gen_eob(s);
6002
        }
6003
        break;
6004

    
6005
        /************************/
6006
        /* shifts */
6007
    case 0xc0:
6008
    case 0xc1:
6009
        /* shift Ev,Ib */
6010
        shift = 2;
6011
    grp2:
6012
        {
6013
            if ((b & 1) == 0)
6014
                ot = OT_BYTE;
6015
            else
6016
                ot = dflag + OT_WORD;
6017

    
6018
            modrm = cpu_ldub_code(env, s->pc++);
6019
            mod = (modrm >> 6) & 3;
6020
            op = (modrm >> 3) & 7;
6021

    
6022
            if (mod != 3) {
6023
                if (shift == 2) {
6024
                    s->rip_offset = 1;
6025
                }
6026
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
6027
                opreg = OR_TMP0;
6028
            } else {
6029
                opreg = (modrm & 7) | REX_B(s);
6030
            }
6031

    
6032
            /* simpler op */
6033
            if (shift == 0) {
6034
                gen_shift(s, op, ot, opreg, OR_ECX);
6035
            } else {
6036
                if (shift == 2) {
6037
                    shift = cpu_ldub_code(env, s->pc++);
6038
                }
6039
                gen_shifti(s, op, ot, opreg, shift);
6040
            }
6041
        }
6042
        break;
6043
    case 0xd0:
6044
    case 0xd1:
6045
        /* shift Ev,1 */
6046
        shift = 1;
6047
        goto grp2;
6048
    case 0xd2:
6049
    case 0xd3:
6050
        /* shift Ev,cl */
6051
        shift = 0;
6052
        goto grp2;
6053

    
6054
    case 0x1a4: /* shld imm */
6055
        op = 0;
6056
        shift = 1;
6057
        goto do_shiftd;
6058
    case 0x1a5: /* shld cl */
6059
        op = 0;
6060
        shift = 0;
6061
        goto do_shiftd;
6062
    case 0x1ac: /* shrd imm */
6063
        op = 1;
6064
        shift = 1;
6065
        goto do_shiftd;
6066
    case 0x1ad: /* shrd cl */
6067
        op = 1;
6068
        shift = 0;
6069
    do_shiftd:
6070
        ot = dflag + OT_WORD;
6071
        modrm = cpu_ldub_code(env, s->pc++);
6072
        mod = (modrm >> 6) & 3;
6073
        rm = (modrm & 7) | REX_B(s);
6074
        reg = ((modrm >> 3) & 7) | rex_r;
6075
        if (mod != 3) {
6076
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
6077
            opreg = OR_TMP0;
6078
        } else {
6079
            opreg = rm;
6080
        }
6081
        gen_op_mov_TN_reg(ot, 1, reg);
6082

    
6083
        if (shift) {
6084
            TCGv imm = tcg_const_tl(cpu_ldub_code(env, s->pc++));
6085
            gen_shiftd_rm_T1(s, ot, opreg, op, imm);
6086
            tcg_temp_free(imm);
6087
        } else {
6088
            gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]);
6089
        }
6090
        break;
6091

    
6092
        /************************/
6093
        /* floats */
6094
    case 0xd8 ... 0xdf:
6095
        if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
6096
            /* if CR0.EM or CR0.TS are set, generate an FPU exception */
6097
            /* XXX: what to do if illegal op ? */
6098
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6099
            break;
6100
        }
6101
        modrm = cpu_ldub_code(env, s->pc++);
6102
        mod = (modrm >> 6) & 3;
6103
        rm = modrm & 7;
6104
        op = ((b & 7) << 3) | ((modrm >> 3) & 7);
6105
        if (mod != 3) {
6106
            /* memory op */
6107
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
6108
            switch(op) {
6109
            case 0x00 ... 0x07: /* fxxxs */
6110
            case 0x10 ... 0x17: /* fixxxl */
6111
            case 0x20 ... 0x27: /* fxxxl */
6112
            case 0x30 ... 0x37: /* fixxx */
6113
                {
6114
                    int op1;
6115
                    op1 = op & 7;
6116

    
6117
                    switch(op >> 4) {
6118
                    case 0:
6119
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
6120
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6121
                        gen_helper_flds_FT0(cpu_env, cpu_tmp2_i32);
6122
                        break;
6123
                    case 1:
6124
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
6125
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6126
                        gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
6127
                        break;
6128
                    case 2:
6129
                        tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
6130
                                          (s->mem_index >> 2) - 1);
6131
                        gen_helper_fldl_FT0(cpu_env, cpu_tmp1_i64);
6132
                        break;
6133
                    case 3:
6134
                    default:
6135
                        gen_op_lds_T0_A0(OT_WORD + s->mem_index);
6136
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6137
                        gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
6138
                        break;
6139
                    }
6140

    
6141
                    gen_helper_fp_arith_ST0_FT0(op1);
6142
                    if (op1 == 3) {
6143
                        /* fcomp needs pop */
6144
                        gen_helper_fpop(cpu_env);
6145
                    }
6146
                }
6147
                break;
6148
            case 0x08: /* flds */
6149
            case 0x0a: /* fsts */
6150
            case 0x0b: /* fstps */
6151
            case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
6152
            case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
6153
            case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
6154
                switch(op & 7) {
6155
                case 0:
6156
                    switch(op >> 4) {
6157
                    case 0:
6158
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
6159
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6160
                        gen_helper_flds_ST0(cpu_env, cpu_tmp2_i32);
6161
                        break;
6162
                    case 1:
6163
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
6164
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6165
                        gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
6166
                        break;
6167
                    case 2:
6168
                        tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
6169
                                          (s->mem_index >> 2) - 1);
6170
                        gen_helper_fldl_ST0(cpu_env, cpu_tmp1_i64);
6171
                        break;
6172
                    case 3:
6173
                    default:
6174
                        gen_op_lds_T0_A0(OT_WORD + s->mem_index);
6175
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6176
                        gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
6177
                        break;
6178
                    }
6179
                    break;
6180
                case 1:
6181
                    /* XXX: the corresponding CPUID bit must be tested ! */
6182
                    switch(op >> 4) {
6183
                    case 1:
6184
                        gen_helper_fisttl_ST0(cpu_tmp2_i32, cpu_env);
6185
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
6186
                        gen_op_st_T0_A0(OT_LONG + s->mem_index);
6187
                        break;
6188
                    case 2:
6189
                        gen_helper_fisttll_ST0(cpu_tmp1_i64, cpu_env);
6190
                        tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
6191
                                          (s->mem_index >> 2) - 1);
6192
                        break;
6193
                    case 3:
6194
                    default:
6195
                        gen_helper_fistt_ST0(cpu_tmp2_i32, cpu_env);
6196
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
6197
                        gen_op_st_T0_A0(OT_WORD + s->mem_index);
6198
                        break;
6199
                    }
6200
                    gen_helper_fpop(cpu_env);
6201
                    break;
6202
                default:
6203
                    switch(op >> 4) {
6204
                    case 0:
6205
                        gen_helper_fsts_ST0(cpu_tmp2_i32, cpu_env);
6206
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
6207
                        gen_op_st_T0_A0(OT_LONG + s->mem_index);
6208
                        break;
6209
                    case 1:
6210
                        gen_helper_fistl_ST0(cpu_tmp2_i32, cpu_env);
6211
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
6212
                        gen_op_st_T0_A0(OT_LONG + s->mem_index);
6213
                        break;
6214
                    case 2:
6215
                        gen_helper_fstl_ST0(cpu_tmp1_i64, cpu_env);
6216
                        tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
6217
                                          (s->mem_index >> 2) - 1);
6218
                        break;
6219
                    case 3:
6220
                    default:
6221
                        gen_helper_fist_ST0(cpu_tmp2_i32, cpu_env);
6222
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
6223
                        gen_op_st_T0_A0(OT_WORD + s->mem_index);
6224
                        break;
6225
                    }
6226
                    if ((op & 7) == 3)
6227
                        gen_helper_fpop(cpu_env);
6228
                    break;
6229
                }
6230
                break;
6231
            case 0x0c: /* fldenv mem */
6232
                gen_update_cc_op(s);
6233
                gen_jmp_im(pc_start - s->cs_base);
6234
                gen_helper_fldenv(cpu_env, cpu_A0, tcg_const_i32(s->dflag));
6235
                break;
6236
            case 0x0d: /* fldcw mem */
6237
                gen_op_ld_T0_A0(OT_WORD + s->mem_index);
6238
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6239
                gen_helper_fldcw(cpu_env, cpu_tmp2_i32);
6240
                break;
6241
            case 0x0e: /* fnstenv mem */
6242
                gen_update_cc_op(s);
6243
                gen_jmp_im(pc_start - s->cs_base);
6244
                gen_helper_fstenv(cpu_env, cpu_A0, tcg_const_i32(s->dflag));
6245
                break;
6246
            case 0x0f: /* fnstcw mem */
6247
                gen_helper_fnstcw(cpu_tmp2_i32, cpu_env);
6248
                tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
6249
                gen_op_st_T0_A0(OT_WORD + s->mem_index);
6250
                break;
6251
            case 0x1d: /* fldt mem */
6252
                gen_update_cc_op(s);
6253
                gen_jmp_im(pc_start - s->cs_base);
6254
                gen_helper_fldt_ST0(cpu_env, cpu_A0);
6255
                break;
6256
            case 0x1f: /* fstpt mem */
6257
                gen_update_cc_op(s);
6258
                gen_jmp_im(pc_start - s->cs_base);
6259
                gen_helper_fstt_ST0(cpu_env, cpu_A0);
6260
                gen_helper_fpop(cpu_env);
6261
                break;
6262
            case 0x2c: /* frstor mem */
6263
                gen_update_cc_op(s);
6264
                gen_jmp_im(pc_start - s->cs_base);
6265
                gen_helper_frstor(cpu_env, cpu_A0, tcg_const_i32(s->dflag));
6266
                break;
6267
            case 0x2e: /* fnsave mem */
6268
                gen_update_cc_op(s);
6269
                gen_jmp_im(pc_start - s->cs_base);
6270
                gen_helper_fsave(cpu_env, cpu_A0, tcg_const_i32(s->dflag));
6271
                break;
6272
            case 0x2f: /* fnstsw mem */
6273
                gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
6274
                tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
6275
                gen_op_st_T0_A0(OT_WORD + s->mem_index);
6276
                break;
6277
            case 0x3c: /* fbld */
6278
                gen_update_cc_op(s);
6279
                gen_jmp_im(pc_start - s->cs_base);
6280
                gen_helper_fbld_ST0(cpu_env, cpu_A0);
6281
                break;
6282
            case 0x3e: /* fbstp */
6283
                gen_update_cc_op(s);
6284
                gen_jmp_im(pc_start - s->cs_base);
6285
                gen_helper_fbst_ST0(cpu_env, cpu_A0);
6286
                gen_helper_fpop(cpu_env);
6287
                break;
6288
            case 0x3d: /* fildll */
6289
                tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
6290
                                  (s->mem_index >> 2) - 1);
6291
                gen_helper_fildll_ST0(cpu_env, cpu_tmp1_i64);
6292
                break;
6293
            case 0x3f: /* fistpll */
6294
                gen_helper_fistll_ST0(cpu_tmp1_i64, cpu_env);
6295
                tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
6296
                                  (s->mem_index >> 2) - 1);
6297
                gen_helper_fpop(cpu_env);
6298
                break;
6299
            default:
6300
                goto illegal_op;
6301
            }
6302
        } else {
6303
            /* register float ops */
6304
            opreg = rm;
6305

    
6306
            switch(op) {
6307
            case 0x08: /* fld sti */
6308
                gen_helper_fpush(cpu_env);
6309
                gen_helper_fmov_ST0_STN(cpu_env,
6310
                                        tcg_const_i32((opreg + 1) & 7));
6311
                break;
6312
            case 0x09: /* fxchg sti */
6313
            case 0x29: /* fxchg4 sti, undocumented op */
6314
            case 0x39: /* fxchg7 sti, undocumented op */
6315
                gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg));
6316
                break;
6317
            case 0x0a: /* grp d9/2 */
6318
                switch(rm) {
6319
                case 0: /* fnop */
6320
                    /* check exceptions (FreeBSD FPU probe) */
6321
                    gen_update_cc_op(s);
6322
                    gen_jmp_im(pc_start - s->cs_base);
6323
                    gen_helper_fwait(cpu_env);
6324
                    break;
6325
                default:
6326
                    goto illegal_op;
6327
                }
6328
                break;
6329
            case 0x0c: /* grp d9/4 */
6330
                switch(rm) {
6331
                case 0: /* fchs */
6332
                    gen_helper_fchs_ST0(cpu_env);
6333
                    break;
6334
                case 1: /* fabs */
6335
                    gen_helper_fabs_ST0(cpu_env);
6336
                    break;
6337
                case 4: /* ftst */
6338
                    gen_helper_fldz_FT0(cpu_env);
6339
                    gen_helper_fcom_ST0_FT0(cpu_env);
6340
                    break;
6341
                case 5: /* fxam */
6342
                    gen_helper_fxam_ST0(cpu_env);
6343
                    break;
6344
                default:
6345
                    goto illegal_op;
6346
                }
6347
                break;
6348
            case 0x0d: /* grp d9/5 */
6349
                {
6350
                    switch(rm) {
6351
                    case 0:
6352
                        gen_helper_fpush(cpu_env);
6353
                        gen_helper_fld1_ST0(cpu_env);
6354
                        break;
6355
                    case 1:
6356
                        gen_helper_fpush(cpu_env);
6357
                        gen_helper_fldl2t_ST0(cpu_env);
6358
                        break;
6359
                    case 2:
6360
                        gen_helper_fpush(cpu_env);
6361
                        gen_helper_fldl2e_ST0(cpu_env);
6362
                        break;
6363
                    case 3:
6364
                        gen_helper_fpush(cpu_env);
6365
                        gen_helper_fldpi_ST0(cpu_env);
6366
                        break;
6367
                    case 4:
6368
                        gen_helper_fpush(cpu_env);
6369
                        gen_helper_fldlg2_ST0(cpu_env);
6370
                        break;
6371
                    case 5:
6372
                        gen_helper_fpush(cpu_env);
6373
                        gen_helper_fldln2_ST0(cpu_env);
6374
                        break;
6375
                    case 6:
6376
                        gen_helper_fpush(cpu_env);
6377
                        gen_helper_fldz_ST0(cpu_env);
6378
                        break;
6379
                    default:
6380
                        goto illegal_op;
6381
                    }
6382
                }
6383
                break;
6384
            case 0x0e: /* grp d9/6 */
6385
                switch(rm) {
6386
                case 0: /* f2xm1 */
6387
                    gen_helper_f2xm1(cpu_env);
6388
                    break;
6389
                case 1: /* fyl2x */
6390
                    gen_helper_fyl2x(cpu_env);
6391
                    break;
6392
                case 2: /* fptan */
6393
                    gen_helper_fptan(cpu_env);
6394
                    break;
6395
                case 3: /* fpatan */
6396
                    gen_helper_fpatan(cpu_env);
6397
                    break;
6398
                case 4: /* fxtract */
6399
                    gen_helper_fxtract(cpu_env);
6400
                    break;
6401
                case 5: /* fprem1 */
6402
                    gen_helper_fprem1(cpu_env);
6403
                    break;
6404
                case 6: /* fdecstp */
6405
                    gen_helper_fdecstp(cpu_env);
6406
                    break;
6407
                default:
6408
                case 7: /* fincstp */
6409
                    gen_helper_fincstp(cpu_env);
6410
                    break;
6411
                }
6412
                break;
6413
            case 0x0f: /* grp d9/7 */
6414
                switch(rm) {
6415
                case 0: /* fprem */
6416
                    gen_helper_fprem(cpu_env);
6417
                    break;
6418
                case 1: /* fyl2xp1 */
6419
                    gen_helper_fyl2xp1(cpu_env);
6420
                    break;
6421
                case 2: /* fsqrt */
6422
                    gen_helper_fsqrt(cpu_env);
6423
                    break;
6424
                case 3: /* fsincos */
6425
                    gen_helper_fsincos(cpu_env);
6426
                    break;
6427
                case 5: /* fscale */
6428
                    gen_helper_fscale(cpu_env);
6429
                    break;
6430
                case 4: /* frndint */
6431
                    gen_helper_frndint(cpu_env);
6432
                    break;
6433
                case 6: /* fsin */
6434
                    gen_helper_fsin(cpu_env);
6435
                    break;
6436
                default:
6437
                case 7: /* fcos */
6438
                    gen_helper_fcos(cpu_env);
6439
                    break;
6440
                }
6441
                break;
6442
            case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6443
            case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6444
            case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6445
                {
6446
                    int op1;
6447

    
6448
                    op1 = op & 7;
6449
                    if (op >= 0x20) {
6450
                        gen_helper_fp_arith_STN_ST0(op1, opreg);
6451
                        if (op >= 0x30)
6452
                            gen_helper_fpop(cpu_env);
6453
                    } else {
6454
                        gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6455
                        gen_helper_fp_arith_ST0_FT0(op1);
6456
                    }
6457
                }
6458
                break;
6459
            case 0x02: /* fcom */
6460
            case 0x22: /* fcom2, undocumented op */
6461
                gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6462
                gen_helper_fcom_ST0_FT0(cpu_env);
6463
                break;
6464
            case 0x03: /* fcomp */
6465
            case 0x23: /* fcomp3, undocumented op */
6466
            case 0x32: /* fcomp5, undocumented op */
6467
                gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6468
                gen_helper_fcom_ST0_FT0(cpu_env);
6469
                gen_helper_fpop(cpu_env);
6470
                break;
6471
            case 0x15: /* da/5 */
6472
                switch(rm) {
6473
                case 1: /* fucompp */
6474
                    gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6475
                    gen_helper_fucom_ST0_FT0(cpu_env);
6476
                    gen_helper_fpop(cpu_env);
6477
                    gen_helper_fpop(cpu_env);
6478
                    break;
6479
                default:
6480
                    goto illegal_op;
6481
                }
6482
                break;
6483
            case 0x1c:
6484
                switch(rm) {
6485
                case 0: /* feni (287 only, just do nop here) */
6486
                    break;
6487
                case 1: /* fdisi (287 only, just do nop here) */
6488
                    break;
6489
                case 2: /* fclex */
6490
                    gen_helper_fclex(cpu_env);
6491
                    break;
6492
                case 3: /* fninit */
6493
                    gen_helper_fninit(cpu_env);
6494
                    break;
6495
                case 4: /* fsetpm (287 only, just do nop here) */
6496
                    break;
6497
                default:
6498
                    goto illegal_op;
6499
                }
6500
                break;
6501
            case 0x1d: /* fucomi */
6502
                gen_update_cc_op(s);
6503
                gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6504
                gen_helper_fucomi_ST0_FT0(cpu_env);
6505
                set_cc_op(s, CC_OP_EFLAGS);
6506
                break;
6507
            case 0x1e: /* fcomi */
6508
                gen_update_cc_op(s);
6509
                gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6510
                gen_helper_fcomi_ST0_FT0(cpu_env);
6511
                set_cc_op(s, CC_OP_EFLAGS);
6512
                break;
6513
            case 0x28: /* ffree sti */
6514
                gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6515
                break;
6516
            case 0x2a: /* fst sti */
6517
                gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6518
                break;
6519
            case 0x2b: /* fstp sti */
6520
            case 0x0b: /* fstp1 sti, undocumented op */
6521
            case 0x3a: /* fstp8 sti, undocumented op */
6522
            case 0x3b: /* fstp9 sti, undocumented op */
6523
                gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6524
                gen_helper_fpop(cpu_env);
6525
                break;
6526
            case 0x2c: /* fucom st(i) */
6527
                gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6528
                gen_helper_fucom_ST0_FT0(cpu_env);
6529
                break;
6530
            case 0x2d: /* fucomp st(i) */
6531
                gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6532
                gen_helper_fucom_ST0_FT0(cpu_env);
6533
                gen_helper_fpop(cpu_env);
6534
                break;
6535
            case 0x33: /* de/3 */
6536
                switch(rm) {
6537
                case 1: /* fcompp */
6538
                    gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6539
                    gen_helper_fcom_ST0_FT0(cpu_env);
6540
                    gen_helper_fpop(cpu_env);
6541
                    gen_helper_fpop(cpu_env);
6542
                    break;
6543
                default:
6544
                    goto illegal_op;
6545
                }
6546
                break;
6547
            case 0x38: /* ffreep sti, undocumented op */
6548
                gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6549
                gen_helper_fpop(cpu_env);
6550
                break;
6551
            case 0x3c: /* df/4 */
6552
                switch(rm) {
6553
                case 0:
6554
                    gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
6555
                    tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
6556
                    gen_op_mov_reg_T0(OT_WORD, R_EAX);
6557
                    break;
6558
                default:
6559
                    goto illegal_op;
6560
                }
6561
                break;
6562
            case 0x3d: /* fucomip */
6563
                gen_update_cc_op(s);
6564
                gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6565
                gen_helper_fucomi_ST0_FT0(cpu_env);
6566
                gen_helper_fpop(cpu_env);
6567
                set_cc_op(s, CC_OP_EFLAGS);
6568
                break;
6569
            case 0x3e: /* fcomip */
6570
                gen_update_cc_op(s);
6571
                gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6572
                gen_helper_fcomi_ST0_FT0(cpu_env);
6573
                gen_helper_fpop(cpu_env);
6574
                set_cc_op(s, CC_OP_EFLAGS);
6575
                break;
6576
            case 0x10 ... 0x13: /* fcmovxx */
6577
            case 0x18 ... 0x1b:
6578
                {
6579
                    int op1, l1;
6580
                    static const uint8_t fcmov_cc[8] = {
6581
                        (JCC_B << 1),
6582
                        (JCC_Z << 1),
6583
                        (JCC_BE << 1),
6584
                        (JCC_P << 1),
6585
                    };
6586
                    op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
6587
                    l1 = gen_new_label();
6588
                    gen_jcc1_noeob(s, op1, l1);
6589
                    gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg));
6590
                    gen_set_label(l1);
6591
                }
6592
                break;
6593
            default:
6594
                goto illegal_op;
6595
            }
6596
        }
6597
        break;
6598
        /************************/
6599
        /* string ops */
6600

    
6601
    case 0xa4: /* movsS */
6602
    case 0xa5:
6603
        if ((b & 1) == 0)
6604
            ot = OT_BYTE;
6605
        else
6606
            ot = dflag + OT_WORD;
6607

    
6608
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6609
            gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6610
        } else {
6611
            gen_movs(s, ot);
6612
        }
6613
        break;
6614

    
6615
    case 0xaa: /* stosS */
6616
    case 0xab:
6617
        if ((b & 1) == 0)
6618
            ot = OT_BYTE;
6619
        else
6620
            ot = dflag + OT_WORD;
6621

    
6622
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6623
            gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6624
        } else {
6625
            gen_stos(s, ot);
6626
        }
6627
        break;
6628
    case 0xac: /* lodsS */
6629
    case 0xad:
6630
        if ((b & 1) == 0)
6631
            ot = OT_BYTE;
6632
        else
6633
            ot = dflag + OT_WORD;
6634
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6635
            gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6636
        } else {
6637
            gen_lods(s, ot);
6638
        }
6639
        break;
6640
    case 0xae: /* scasS */
6641
    case 0xaf:
6642
        if ((b & 1) == 0)
6643
            ot = OT_BYTE;
6644
        else
6645
            ot = dflag + OT_WORD;
6646
        if (prefixes & PREFIX_REPNZ) {
6647
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6648
        } else if (prefixes & PREFIX_REPZ) {
6649
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6650
        } else {
6651
            gen_scas(s, ot);
6652
        }
6653
        break;
6654

    
6655
    case 0xa6: /* cmpsS */
6656
    case 0xa7:
6657
        if ((b & 1) == 0)
6658
            ot = OT_BYTE;
6659
        else
6660
            ot = dflag + OT_WORD;
6661
        if (prefixes & PREFIX_REPNZ) {
6662
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6663
        } else if (prefixes & PREFIX_REPZ) {
6664
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6665
        } else {
6666
            gen_cmps(s, ot);
6667
        }
6668
        break;
6669
    case 0x6c: /* insS */
6670
    case 0x6d:
6671
        if ((b & 1) == 0)
6672
            ot = OT_BYTE;
6673
        else
6674
            ot = dflag ? OT_LONG : OT_WORD;
6675
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6676
        gen_op_andl_T0_ffff();
6677
        gen_check_io(s, ot, pc_start - s->cs_base, 
6678
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
6679
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6680
            gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6681
        } else {
6682
            gen_ins(s, ot);
6683
            if (use_icount) {
6684
                gen_jmp(s, s->pc - s->cs_base);
6685
            }
6686
        }
6687
        break;
6688
    case 0x6e: /* outsS */
6689
    case 0x6f:
6690
        if ((b & 1) == 0)
6691
            ot = OT_BYTE;
6692
        else
6693
            ot = dflag ? OT_LONG : OT_WORD;
6694
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6695
        gen_op_andl_T0_ffff();
6696
        gen_check_io(s, ot, pc_start - s->cs_base,
6697
                     svm_is_rep(prefixes) | 4);
6698
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6699
            gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6700
        } else {
6701
            gen_outs(s, ot);
6702
            if (use_icount) {
6703
                gen_jmp(s, s->pc - s->cs_base);
6704
            }
6705
        }
6706
        break;
6707

    
6708
        /************************/
6709
        /* port I/O */
6710

    
6711
    case 0xe4:
6712
    case 0xe5:
6713
        if ((b & 1) == 0)
6714
            ot = OT_BYTE;
6715
        else
6716
            ot = dflag ? OT_LONG : OT_WORD;
6717
        val = cpu_ldub_code(env, s->pc++);
6718
        gen_op_movl_T0_im(val);
6719
        gen_check_io(s, ot, pc_start - s->cs_base,
6720
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6721
        if (use_icount)
6722
            gen_io_start();
6723
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6724
        gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
6725
        gen_op_mov_reg_T1(ot, R_EAX);
6726
        if (use_icount) {
6727
            gen_io_end();
6728
            gen_jmp(s, s->pc - s->cs_base);
6729
        }
6730
        break;
6731
    case 0xe6:
6732
    case 0xe7:
6733
        if ((b & 1) == 0)
6734
            ot = OT_BYTE;
6735
        else
6736
            ot = dflag ? OT_LONG : OT_WORD;
6737
        val = cpu_ldub_code(env, s->pc++);
6738
        gen_op_movl_T0_im(val);
6739
        gen_check_io(s, ot, pc_start - s->cs_base,
6740
                     svm_is_rep(prefixes));
6741
        gen_op_mov_TN_reg(ot, 1, R_EAX);
6742

    
6743
        if (use_icount)
6744
            gen_io_start();
6745
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6746
        tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
6747
        gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6748
        if (use_icount) {
6749
            gen_io_end();
6750
            gen_jmp(s, s->pc - s->cs_base);
6751
        }
6752
        break;
6753
    case 0xec:
6754
    case 0xed:
6755
        if ((b & 1) == 0)
6756
            ot = OT_BYTE;
6757
        else
6758
            ot = dflag ? OT_LONG : OT_WORD;
6759
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6760
        gen_op_andl_T0_ffff();
6761
        gen_check_io(s, ot, pc_start - s->cs_base,
6762
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6763
        if (use_icount)
6764
            gen_io_start();
6765
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6766
        gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
6767
        gen_op_mov_reg_T1(ot, R_EAX);
6768
        if (use_icount) {
6769
            gen_io_end();
6770
            gen_jmp(s, s->pc - s->cs_base);
6771
        }
6772
        break;
6773
    case 0xee:
6774
    case 0xef:
6775
        if ((b & 1) == 0)
6776
            ot = OT_BYTE;
6777
        else
6778
            ot = dflag ? OT_LONG : OT_WORD;
6779
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6780
        gen_op_andl_T0_ffff();
6781
        gen_check_io(s, ot, pc_start - s->cs_base,
6782
                     svm_is_rep(prefixes));
6783
        gen_op_mov_TN_reg(ot, 1, R_EAX);
6784

    
6785
        if (use_icount)
6786
            gen_io_start();
6787
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6788
        tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
6789
        gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6790
        if (use_icount) {
6791
            gen_io_end();
6792
            gen_jmp(s, s->pc - s->cs_base);
6793
        }
6794
        break;
6795

    
6796
        /************************/
6797
        /* control */
6798
    case 0xc2: /* ret im */
6799
        val = cpu_ldsw_code(env, s->pc);
6800
        s->pc += 2;
6801
        gen_pop_T0(s);
6802
        if (CODE64(s) && s->dflag)
6803
            s->dflag = 2;
6804
        gen_stack_update(s, val + (2 << s->dflag));
6805
        if (s->dflag == 0)
6806
            gen_op_andl_T0_ffff();
6807
        gen_op_jmp_T0();
6808
        gen_eob(s);
6809
        break;
6810
    case 0xc3: /* ret */
6811
        gen_pop_T0(s);
6812
        gen_pop_update(s);
6813
        if (s->dflag == 0)
6814
            gen_op_andl_T0_ffff();
6815
        gen_op_jmp_T0();
6816
        gen_eob(s);
6817
        break;
6818
    case 0xca: /* lret im */
6819
        val = cpu_ldsw_code(env, s->pc);
6820
        s->pc += 2;
6821
    do_lret:
6822
        if (s->pe && !s->vm86) {
6823
            gen_update_cc_op(s);
6824
            gen_jmp_im(pc_start - s->cs_base);
6825
            gen_helper_lret_protected(cpu_env, tcg_const_i32(s->dflag),
6826
                                      tcg_const_i32(val));
6827
        } else {
6828
            gen_stack_A0(s);
6829
            /* pop offset */
6830
            gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
6831
            if (s->dflag == 0)
6832
                gen_op_andl_T0_ffff();
6833
            /* NOTE: keeping EIP updated is not a problem in case of
6834
               exception */
6835
            gen_op_jmp_T0();
6836
            /* pop selector */
6837
            gen_op_addl_A0_im(2 << s->dflag);
6838
            gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
6839
            gen_op_movl_seg_T0_vm(R_CS);
6840
            /* add stack offset */
6841
            gen_stack_update(s, val + (4 << s->dflag));
6842
        }
6843
        gen_eob(s);
6844
        break;
6845
    case 0xcb: /* lret */
6846
        val = 0;
6847
        goto do_lret;
6848
    case 0xcf: /* iret */
6849
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
6850
        if (!s->pe) {
6851
            /* real mode */
6852
            gen_helper_iret_real(cpu_env, tcg_const_i32(s->dflag));
6853
            set_cc_op(s, CC_OP_EFLAGS);
6854
        } else if (s->vm86) {
6855
            if (s->iopl != 3) {
6856
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6857
            } else {
6858
                gen_helper_iret_real(cpu_env, tcg_const_i32(s->dflag));
6859
                set_cc_op(s, CC_OP_EFLAGS);
6860
            }
6861
        } else {
6862
            gen_update_cc_op(s);
6863
            gen_jmp_im(pc_start - s->cs_base);
6864
            gen_helper_iret_protected(cpu_env, tcg_const_i32(s->dflag),
6865
                                      tcg_const_i32(s->pc - s->cs_base));
6866
            set_cc_op(s, CC_OP_EFLAGS);
6867
        }
6868
        gen_eob(s);
6869
        break;
6870
    case 0xe8: /* call im */
6871
        {
6872
            if (dflag)
6873
                tval = (int32_t)insn_get(env, s, OT_LONG);
6874
            else
6875
                tval = (int16_t)insn_get(env, s, OT_WORD);
6876
            next_eip = s->pc - s->cs_base;
6877
            tval += next_eip;
6878
            if (s->dflag == 0)
6879
                tval &= 0xffff;
6880
            else if(!CODE64(s))
6881
                tval &= 0xffffffff;
6882
            gen_movtl_T0_im(next_eip);
6883
            gen_push_T0(s);
6884
            gen_jmp(s, tval);
6885
        }
6886
        break;
6887
    case 0x9a: /* lcall im */
6888
        {
6889
            unsigned int selector, offset;
6890

    
6891
            if (CODE64(s))
6892
                goto illegal_op;
6893
            ot = dflag ? OT_LONG : OT_WORD;
6894
            offset = insn_get(env, s, ot);
6895
            selector = insn_get(env, s, OT_WORD);
6896

    
6897
            gen_op_movl_T0_im(selector);
6898
            gen_op_movl_T1_imu(offset);
6899
        }
6900
        goto do_lcall;
6901
    case 0xe9: /* jmp im */
6902
        if (dflag)
6903
            tval = (int32_t)insn_get(env, s, OT_LONG);
6904
        else
6905
            tval = (int16_t)insn_get(env, s, OT_WORD);
6906
        tval += s->pc - s->cs_base;
6907
        if (s->dflag == 0)
6908
            tval &= 0xffff;
6909
        else if(!CODE64(s))
6910
            tval &= 0xffffffff;
6911
        gen_jmp(s, tval);
6912
        break;
6913
    case 0xea: /* ljmp im */
6914
        {
6915
            unsigned int selector, offset;
6916

    
6917
            if (CODE64(s))
6918
                goto illegal_op;
6919
            ot = dflag ? OT_LONG : OT_WORD;
6920
            offset = insn_get(env, s, ot);
6921
            selector = insn_get(env, s, OT_WORD);
6922

    
6923
            gen_op_movl_T0_im(selector);
6924
            gen_op_movl_T1_imu(offset);
6925
        }
6926
        goto do_ljmp;
6927
    case 0xeb: /* jmp Jb */
6928
        tval = (int8_t)insn_get(env, s, OT_BYTE);
6929
        tval += s->pc - s->cs_base;
6930
        if (s->dflag == 0)
6931
            tval &= 0xffff;
6932
        gen_jmp(s, tval);
6933
        break;
6934
    case 0x70 ... 0x7f: /* jcc Jb */
6935
        tval = (int8_t)insn_get(env, s, OT_BYTE);
6936
        goto do_jcc;
6937
    case 0x180 ... 0x18f: /* jcc Jv */
6938
        if (dflag) {
6939
            tval = (int32_t)insn_get(env, s, OT_LONG);
6940
        } else {
6941
            tval = (int16_t)insn_get(env, s, OT_WORD);
6942
        }
6943
    do_jcc:
6944
        next_eip = s->pc - s->cs_base;
6945
        tval += next_eip;
6946
        if (s->dflag == 0)
6947
            tval &= 0xffff;
6948
        gen_jcc(s, b, tval, next_eip);
6949
        break;
6950

    
6951
    case 0x190 ... 0x19f: /* setcc Gv */
6952
        modrm = cpu_ldub_code(env, s->pc++);
6953
        gen_setcc1(s, b, cpu_T[0]);
6954
        gen_ldst_modrm(env, s, modrm, OT_BYTE, OR_TMP0, 1);
6955
        break;
6956
    case 0x140 ... 0x14f: /* cmov Gv, Ev */
6957
        ot = dflag + OT_WORD;
6958
        modrm = cpu_ldub_code(env, s->pc++);
6959
        reg = ((modrm >> 3) & 7) | rex_r;
6960
        gen_cmovcc1(env, s, ot, b, modrm, reg);
6961
        break;
6962

    
6963
        /************************/
6964
        /* flags */
6965
    case 0x9c: /* pushf */
6966
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
6967
        if (s->vm86 && s->iopl != 3) {
6968
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6969
        } else {
6970
            gen_update_cc_op(s);
6971
            gen_helper_read_eflags(cpu_T[0], cpu_env);
6972
            gen_push_T0(s);
6973
        }
6974
        break;
6975
    case 0x9d: /* popf */
6976
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
6977
        if (s->vm86 && s->iopl != 3) {
6978
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6979
        } else {
6980
            gen_pop_T0(s);
6981
            if (s->cpl == 0) {
6982
                if (s->dflag) {
6983
                    gen_helper_write_eflags(cpu_env, cpu_T[0],
6984
                                            tcg_const_i32((TF_MASK | AC_MASK |
6985
                                                           ID_MASK | NT_MASK |
6986
                                                           IF_MASK |
6987
                                                           IOPL_MASK)));
6988
                } else {
6989
                    gen_helper_write_eflags(cpu_env, cpu_T[0],
6990
                                            tcg_const_i32((TF_MASK | AC_MASK |
6991
                                                           ID_MASK | NT_MASK |
6992
                                                           IF_MASK | IOPL_MASK)
6993
                                                          & 0xffff));
6994
                }
6995
            } else {
6996
                if (s->cpl <= s->iopl) {
6997
                    if (s->dflag) {
6998
                        gen_helper_write_eflags(cpu_env, cpu_T[0],
6999
                                                tcg_const_i32((TF_MASK |
7000
                                                               AC_MASK |
7001
                                                               ID_MASK |
7002
                                                               NT_MASK |
7003
                                                               IF_MASK)));
7004
                    } else {
7005
                        gen_helper_write_eflags(cpu_env, cpu_T[0],
7006
                                                tcg_const_i32((TF_MASK |
7007
                                                               AC_MASK |
7008
                                                               ID_MASK |
7009
                                                               NT_MASK |
7010
                                                               IF_MASK)
7011
                                                              & 0xffff));
7012
                    }
7013
                } else {
7014
                    if (s->dflag) {
7015
                        gen_helper_write_eflags(cpu_env, cpu_T[0],
7016
                                           tcg_const_i32((TF_MASK | AC_MASK |
7017
                                                          ID_MASK | NT_MASK)));
7018
                    } else {
7019
                        gen_helper_write_eflags(cpu_env, cpu_T[0],
7020
                                           tcg_const_i32((TF_MASK | AC_MASK |
7021
                                                          ID_MASK | NT_MASK)
7022
                                                         & 0xffff));
7023
                    }
7024
                }
7025
            }
7026
            gen_pop_update(s);
7027
            set_cc_op(s, CC_OP_EFLAGS);
7028
            /* abort translation because TF/AC flag may change */
7029
            gen_jmp_im(s->pc - s->cs_base);
7030
            gen_eob(s);
7031
        }
7032
        break;
7033
    case 0x9e: /* sahf */
7034
        if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
7035
            goto illegal_op;
7036
        gen_op_mov_TN_reg(OT_BYTE, 0, R_AH);
7037
        gen_compute_eflags(s);
7038
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
7039
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], CC_S | CC_Z | CC_A | CC_P | CC_C);
7040
        tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T[0]);
7041
        break;
7042
    case 0x9f: /* lahf */
7043
        if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
7044
            goto illegal_op;
7045
        gen_compute_eflags(s);
7046
        /* Note: gen_compute_eflags() only gives the condition codes */
7047
        tcg_gen_ori_tl(cpu_T[0], cpu_cc_src, 0x02);
7048
        gen_op_mov_reg_T0(OT_BYTE, R_AH);
7049
        break;
7050
    case 0xf5: /* cmc */
7051
        gen_compute_eflags(s);
7052
        tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
7053
        break;
7054
    case 0xf8: /* clc */
7055
        gen_compute_eflags(s);
7056
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
7057
        break;
7058
    case 0xf9: /* stc */
7059
        gen_compute_eflags(s);
7060
        tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
7061
        break;
7062
    case 0xfc: /* cld */
7063
        tcg_gen_movi_i32(cpu_tmp2_i32, 1);
7064
        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
7065
        break;
7066
    case 0xfd: /* std */
7067
        tcg_gen_movi_i32(cpu_tmp2_i32, -1);
7068
        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
7069
        break;
7070

    
7071
        /************************/
7072
        /* bit operations */
7073
    case 0x1ba: /* bt/bts/btr/btc Gv, im */
7074
        ot = dflag + OT_WORD;
7075
        modrm = cpu_ldub_code(env, s->pc++);
7076
        op = (modrm >> 3) & 7;
7077
        mod = (modrm >> 6) & 3;
7078
        rm = (modrm & 7) | REX_B(s);
7079
        if (mod != 3) {
7080
            s->rip_offset = 1;
7081
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7082
            gen_op_ld_T0_A0(ot + s->mem_index);
7083
        } else {
7084
            gen_op_mov_TN_reg(ot, 0, rm);
7085
        }
7086
        /* load shift */
7087
        val = cpu_ldub_code(env, s->pc++);
7088
        gen_op_movl_T1_im(val);
7089
        if (op < 4)
7090
            goto illegal_op;
7091
        op -= 4;
7092
        goto bt_op;
7093
    case 0x1a3: /* bt Gv, Ev */
7094
        op = 0;
7095
        goto do_btx;
7096
    case 0x1ab: /* bts */
7097
        op = 1;
7098
        goto do_btx;
7099
    case 0x1b3: /* btr */
7100
        op = 2;
7101
        goto do_btx;
7102
    case 0x1bb: /* btc */
7103
        op = 3;
7104
    do_btx:
7105
        ot = dflag + OT_WORD;
7106
        modrm = cpu_ldub_code(env, s->pc++);
7107
        reg = ((modrm >> 3) & 7) | rex_r;
7108
        mod = (modrm >> 6) & 3;
7109
        rm = (modrm & 7) | REX_B(s);
7110
        gen_op_mov_TN_reg(OT_LONG, 1, reg);
7111
        if (mod != 3) {
7112
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7113
            /* specific case: we need to add a displacement */
7114
            gen_exts(ot, cpu_T[1]);
7115
            tcg_gen_sari_tl(cpu_tmp0, cpu_T[1], 3 + ot);
7116
            tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
7117
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
7118
            gen_op_ld_T0_A0(ot + s->mem_index);
7119
        } else {
7120
            gen_op_mov_TN_reg(ot, 0, rm);
7121
        }
7122
    bt_op:
7123
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], (1 << (3 + ot)) - 1);
7124
        switch(op) {
7125
        case 0:
7126
            tcg_gen_shr_tl(cpu_cc_src, cpu_T[0], cpu_T[1]);
7127
            tcg_gen_movi_tl(cpu_cc_dst, 0);
7128
            break;
7129
        case 1:
7130
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
7131
            tcg_gen_movi_tl(cpu_tmp0, 1);
7132
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
7133
            tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
7134
            break;
7135
        case 2:
7136
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
7137
            tcg_gen_movi_tl(cpu_tmp0, 1);
7138
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
7139
            tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
7140
            tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
7141
            break;
7142
        default:
7143
        case 3:
7144
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
7145
            tcg_gen_movi_tl(cpu_tmp0, 1);
7146
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
7147
            tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
7148
            break;
7149
        }
7150
        set_cc_op(s, CC_OP_SARB + ot);
7151
        if (op != 0) {
7152
            if (mod != 3)
7153
                gen_op_st_T0_A0(ot + s->mem_index);
7154
            else
7155
                gen_op_mov_reg_T0(ot, rm);
7156
            tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
7157
            tcg_gen_movi_tl(cpu_cc_dst, 0);
7158
        }
7159
        break;
7160
    case 0x1bc: /* bsf / tzcnt */
7161
    case 0x1bd: /* bsr / lzcnt */
7162
        ot = dflag + OT_WORD;
7163
        modrm = cpu_ldub_code(env, s->pc++);
7164
        reg = ((modrm >> 3) & 7) | rex_r;
7165
        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
7166
        gen_extu(ot, cpu_T[0]);
7167

    
7168
        /* Note that lzcnt and tzcnt are in different extensions.  */
7169
        if ((prefixes & PREFIX_REPZ)
7170
            && (b & 1
7171
                ? s->cpuid_ext3_features & CPUID_EXT3_ABM
7172
                : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) {
7173
            int size = 8 << ot;
7174
            tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
7175
            if (b & 1) {
7176
                /* For lzcnt, reduce the target_ulong result by the
7177
                   number of zeros that we expect to find at the top.  */
7178
                gen_helper_clz(cpu_T[0], cpu_T[0]);
7179
                tcg_gen_subi_tl(cpu_T[0], cpu_T[0], TARGET_LONG_BITS - size);
7180
            } else {
7181
                /* For tzcnt, a zero input must return the operand size:
7182
                   force all bits outside the operand size to 1.  */
7183
                target_ulong mask = (target_ulong)-2 << (size - 1);
7184
                tcg_gen_ori_tl(cpu_T[0], cpu_T[0], mask);
7185
                gen_helper_ctz(cpu_T[0], cpu_T[0]);
7186
            }
7187
            /* For lzcnt/tzcnt, C and Z bits are defined and are
7188
               related to the result.  */
7189
            gen_op_update1_cc();
7190
            set_cc_op(s, CC_OP_BMILGB + ot);
7191
        } else {
7192
            /* For bsr/bsf, only the Z bit is defined and it is related
7193
               to the input and not the result.  */
7194
            tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
7195
            set_cc_op(s, CC_OP_LOGICB + ot);
7196
            if (b & 1) {
7197
                /* For bsr, return the bit index of the first 1 bit,
7198
                   not the count of leading zeros.  */
7199
                gen_helper_clz(cpu_T[0], cpu_T[0]);
7200
                tcg_gen_xori_tl(cpu_T[0], cpu_T[0], TARGET_LONG_BITS - 1);
7201
            } else {
7202
                gen_helper_ctz(cpu_T[0], cpu_T[0]);
7203
            }
7204
            /* ??? The manual says that the output is undefined when the
7205
               input is zero, but real hardware leaves it unchanged, and
7206
               real programs appear to depend on that.  */
7207
            tcg_gen_movi_tl(cpu_tmp0, 0);
7208
            tcg_gen_movcond_tl(TCG_COND_EQ, cpu_T[0], cpu_cc_dst, cpu_tmp0,
7209
                               cpu_regs[reg], cpu_T[0]);
7210
        }
7211
        gen_op_mov_reg_T0(ot, reg);
7212
        break;
7213
        /************************/
7214
        /* bcd */
7215
    case 0x27: /* daa */
7216
        if (CODE64(s))
7217
            goto illegal_op;
7218
        gen_update_cc_op(s);
7219
        gen_helper_daa(cpu_env);
7220
        set_cc_op(s, CC_OP_EFLAGS);
7221
        break;
7222
    case 0x2f: /* das */
7223
        if (CODE64(s))
7224
            goto illegal_op;
7225
        gen_update_cc_op(s);
7226
        gen_helper_das(cpu_env);
7227
        set_cc_op(s, CC_OP_EFLAGS);
7228
        break;
7229
    case 0x37: /* aaa */
7230
        if (CODE64(s))
7231
            goto illegal_op;
7232
        gen_update_cc_op(s);
7233
        gen_helper_aaa(cpu_env);
7234
        set_cc_op(s, CC_OP_EFLAGS);
7235
        break;
7236
    case 0x3f: /* aas */
7237
        if (CODE64(s))
7238
            goto illegal_op;
7239
        gen_update_cc_op(s);
7240
        gen_helper_aas(cpu_env);
7241
        set_cc_op(s, CC_OP_EFLAGS);
7242
        break;
7243
    case 0xd4: /* aam */
7244
        if (CODE64(s))
7245
            goto illegal_op;
7246
        val = cpu_ldub_code(env, s->pc++);
7247
        if (val == 0) {
7248
            gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
7249
        } else {
7250
            gen_helper_aam(cpu_env, tcg_const_i32(val));
7251
            set_cc_op(s, CC_OP_LOGICB);
7252
        }
7253
        break;
7254
    case 0xd5: /* aad */
7255
        if (CODE64(s))
7256
            goto illegal_op;
7257
        val = cpu_ldub_code(env, s->pc++);
7258
        gen_helper_aad(cpu_env, tcg_const_i32(val));
7259
        set_cc_op(s, CC_OP_LOGICB);
7260
        break;
7261
        /************************/
7262
        /* misc */
7263
    case 0x90: /* nop */
7264
        /* XXX: correct lock test for all insn */
7265
        if (prefixes & PREFIX_LOCK) {
7266
            goto illegal_op;
7267
        }
7268
        /* If REX_B is set, then this is xchg eax, r8d, not a nop.  */
7269
        if (REX_B(s)) {
7270
            goto do_xchg_reg_eax;
7271
        }
7272
        if (prefixes & PREFIX_REPZ) {
7273
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_PAUSE);
7274
        }
7275
        break;
7276
    case 0x9b: /* fwait */
7277
        if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
7278
            (HF_MP_MASK | HF_TS_MASK)) {
7279
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7280
        } else {
7281
            gen_update_cc_op(s);
7282
            gen_jmp_im(pc_start - s->cs_base);
7283
            gen_helper_fwait(cpu_env);
7284
        }
7285
        break;
7286
    case 0xcc: /* int3 */
7287
        gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
7288
        break;
7289
    case 0xcd: /* int N */
7290
        val = cpu_ldub_code(env, s->pc++);
7291
        if (s->vm86 && s->iopl != 3) {
7292
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7293
        } else {
7294
            gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
7295
        }
7296
        break;
7297
    case 0xce: /* into */
7298
        if (CODE64(s))
7299
            goto illegal_op;
7300
        gen_update_cc_op(s);
7301
        gen_jmp_im(pc_start - s->cs_base);
7302
        gen_helper_into(cpu_env, tcg_const_i32(s->pc - pc_start));
7303
        break;
7304
#ifdef WANT_ICEBP
7305
    case 0xf1: /* icebp (undocumented, exits to external debugger) */
7306
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
7307
#if 1
7308
        gen_debug(s, pc_start - s->cs_base);
7309
#else
7310
        /* start debug */
7311
        tb_flush(env);
7312
        qemu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
7313
#endif
7314
        break;
7315
#endif
7316
    case 0xfa: /* cli */
7317
        if (!s->vm86) {
7318
            if (s->cpl <= s->iopl) {
7319
                gen_helper_cli(cpu_env);
7320
            } else {
7321
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7322
            }
7323
        } else {
7324
            if (s->iopl == 3) {
7325
                gen_helper_cli(cpu_env);
7326
            } else {
7327
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7328
            }
7329
        }
7330
        break;
7331
    case 0xfb: /* sti */
7332
        if (!s->vm86) {
7333
            if (s->cpl <= s->iopl) {
7334
            gen_sti:
7335
                gen_helper_sti(cpu_env);
7336
                /* interruptions are enabled only the first insn after sti */
7337
                /* If several instructions disable interrupts, only the
7338
                   _first_ does it */
7339
                if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
7340
                    gen_helper_set_inhibit_irq(cpu_env);
7341
                /* give a chance to handle pending irqs */
7342
                gen_jmp_im(s->pc - s->cs_base);
7343
                gen_eob(s);
7344
            } else {
7345
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7346
            }
7347
        } else {
7348
            if (s->iopl == 3) {
7349
                goto gen_sti;
7350
            } else {
7351
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7352
            }
7353
        }
7354
        break;
7355
    case 0x62: /* bound */
7356
        if (CODE64(s))
7357
            goto illegal_op;
7358
        ot = dflag ? OT_LONG : OT_WORD;
7359
        modrm = cpu_ldub_code(env, s->pc++);
7360
        reg = (modrm >> 3) & 7;
7361
        mod = (modrm >> 6) & 3;
7362
        if (mod == 3)
7363
            goto illegal_op;
7364
        gen_op_mov_TN_reg(ot, 0, reg);
7365
        gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7366
        gen_jmp_im(pc_start - s->cs_base);
7367
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
7368
        if (ot == OT_WORD) {
7369
            gen_helper_boundw(cpu_env, cpu_A0, cpu_tmp2_i32);
7370
        } else {
7371
            gen_helper_boundl(cpu_env, cpu_A0, cpu_tmp2_i32);
7372
        }
7373
        break;
7374
    case 0x1c8 ... 0x1cf: /* bswap reg */
7375
        reg = (b & 7) | REX_B(s);
7376
#ifdef TARGET_X86_64
7377
        if (dflag == 2) {
7378
            gen_op_mov_TN_reg(OT_QUAD, 0, reg);
7379
            tcg_gen_bswap64_i64(cpu_T[0], cpu_T[0]);
7380
            gen_op_mov_reg_T0(OT_QUAD, reg);
7381
        } else
7382
#endif
7383
        {
7384
            gen_op_mov_TN_reg(OT_LONG, 0, reg);
7385
            tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
7386
            tcg_gen_bswap32_tl(cpu_T[0], cpu_T[0]);
7387
            gen_op_mov_reg_T0(OT_LONG, reg);
7388
        }
7389
        break;
7390
    case 0xd6: /* salc */
7391
        if (CODE64(s))
7392
            goto illegal_op;
7393
        gen_compute_eflags_c(s, cpu_T[0]);
7394
        tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
7395
        gen_op_mov_reg_T0(OT_BYTE, R_EAX);
7396
        break;
7397
    case 0xe0: /* loopnz */
7398
    case 0xe1: /* loopz */
7399
    case 0xe2: /* loop */
7400
    case 0xe3: /* jecxz */
7401
        {
7402
            int l1, l2, l3;
7403

    
7404
            tval = (int8_t)insn_get(env, s, OT_BYTE);
7405
            next_eip = s->pc - s->cs_base;
7406
            tval += next_eip;
7407
            if (s->dflag == 0)
7408
                tval &= 0xffff;
7409

    
7410
            l1 = gen_new_label();
7411
            l2 = gen_new_label();
7412
            l3 = gen_new_label();
7413
            b &= 3;
7414
            switch(b) {
7415
            case 0: /* loopnz */
7416
            case 1: /* loopz */
7417
                gen_op_add_reg_im(s->aflag, R_ECX, -1);
7418
                gen_op_jz_ecx(s->aflag, l3);
7419
                gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
7420
                break;
7421
            case 2: /* loop */
7422
                gen_op_add_reg_im(s->aflag, R_ECX, -1);
7423
                gen_op_jnz_ecx(s->aflag, l1);
7424
                break;
7425
            default:
7426
            case 3: /* jcxz */
7427
                gen_op_jz_ecx(s->aflag, l1);
7428
                break;
7429
            }
7430

    
7431
            gen_set_label(l3);
7432
            gen_jmp_im(next_eip);
7433
            tcg_gen_br(l2);
7434

    
7435
            gen_set_label(l1);
7436
            gen_jmp_im(tval);
7437
            gen_set_label(l2);
7438
            gen_eob(s);
7439
        }
7440
        break;
7441
    case 0x130: /* wrmsr */
7442
    case 0x132: /* rdmsr */
7443
        if (s->cpl != 0) {
7444
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7445
        } else {
7446
            gen_update_cc_op(s);
7447
            gen_jmp_im(pc_start - s->cs_base);
7448
            if (b & 2) {
7449
                gen_helper_rdmsr(cpu_env);
7450
            } else {
7451
                gen_helper_wrmsr(cpu_env);
7452
            }
7453
        }
7454
        break;
7455
    case 0x131: /* rdtsc */
7456
        gen_update_cc_op(s);
7457
        gen_jmp_im(pc_start - s->cs_base);
7458
        if (use_icount)
7459
            gen_io_start();
7460
        gen_helper_rdtsc(cpu_env);
7461
        if (use_icount) {
7462
            gen_io_end();
7463
            gen_jmp(s, s->pc - s->cs_base);
7464
        }
7465
        break;
7466
    case 0x133: /* rdpmc */
7467
        gen_update_cc_op(s);
7468
        gen_jmp_im(pc_start - s->cs_base);
7469
        gen_helper_rdpmc(cpu_env);
7470
        break;
7471
    case 0x134: /* sysenter */
7472
        /* For Intel SYSENTER is valid on 64-bit */
7473
        if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7474
            goto illegal_op;
7475
        if (!s->pe) {
7476
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7477
        } else {
7478
            gen_update_cc_op(s);
7479
            gen_jmp_im(pc_start - s->cs_base);
7480
            gen_helper_sysenter(cpu_env);
7481
            gen_eob(s);
7482
        }
7483
        break;
7484
    case 0x135: /* sysexit */
7485
        /* For Intel SYSEXIT is valid on 64-bit */
7486
        if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7487
            goto illegal_op;
7488
        if (!s->pe) {
7489
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7490
        } else {
7491
            gen_update_cc_op(s);
7492
            gen_jmp_im(pc_start - s->cs_base);
7493
            gen_helper_sysexit(cpu_env, tcg_const_i32(dflag));
7494
            gen_eob(s);
7495
        }
7496
        break;
7497
#ifdef TARGET_X86_64
7498
    case 0x105: /* syscall */
7499
        /* XXX: is it usable in real mode ? */
7500
        gen_update_cc_op(s);
7501
        gen_jmp_im(pc_start - s->cs_base);
7502
        gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start));
7503
        gen_eob(s);
7504
        break;
7505
    case 0x107: /* sysret */
7506
        if (!s->pe) {
7507
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7508
        } else {
7509
            gen_update_cc_op(s);
7510
            gen_jmp_im(pc_start - s->cs_base);
7511
            gen_helper_sysret(cpu_env, tcg_const_i32(s->dflag));
7512
            /* condition codes are modified only in long mode */
7513
            if (s->lma) {
7514
                set_cc_op(s, CC_OP_EFLAGS);
7515
            }
7516
            gen_eob(s);
7517
        }
7518
        break;
7519
#endif
7520
    case 0x1a2: /* cpuid */
7521
        gen_update_cc_op(s);
7522
        gen_jmp_im(pc_start - s->cs_base);
7523
        gen_helper_cpuid(cpu_env);
7524
        break;
7525
    case 0xf4: /* hlt */
7526
        if (s->cpl != 0) {
7527
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7528
        } else {
7529
            gen_update_cc_op(s);
7530
            gen_jmp_im(pc_start - s->cs_base);
7531
            gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
7532
            s->is_jmp = DISAS_TB_JUMP;
7533
        }
7534
        break;
7535
    case 0x100:
7536
        modrm = cpu_ldub_code(env, s->pc++);
7537
        mod = (modrm >> 6) & 3;
7538
        op = (modrm >> 3) & 7;
7539
        switch(op) {
7540
        case 0: /* sldt */
7541
            if (!s->pe || s->vm86)
7542
                goto illegal_op;
7543
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
7544
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,ldt.selector));
7545
            ot = OT_WORD;
7546
            if (mod == 3)
7547
                ot += s->dflag;
7548
            gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7549
            break;
7550
        case 2: /* lldt */
7551
            if (!s->pe || s->vm86)
7552
                goto illegal_op;
7553
            if (s->cpl != 0) {
7554
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7555
            } else {
7556
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
7557
                gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
7558
                gen_jmp_im(pc_start - s->cs_base);
7559
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
7560
                gen_helper_lldt(cpu_env, cpu_tmp2_i32);
7561
            }
7562
            break;
7563
        case 1: /* str */
7564
            if (!s->pe || s->vm86)
7565
                goto illegal_op;
7566
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
7567
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,tr.selector));
7568
            ot = OT_WORD;
7569
            if (mod == 3)
7570
                ot += s->dflag;
7571
            gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7572
            break;
7573
        case 3: /* ltr */
7574
            if (!s->pe || s->vm86)
7575
                goto illegal_op;
7576
            if (s->cpl != 0) {
7577
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7578
            } else {
7579
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
7580
                gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
7581
                gen_jmp_im(pc_start - s->cs_base);
7582
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
7583
                gen_helper_ltr(cpu_env, cpu_tmp2_i32);
7584
            }
7585
            break;
7586
        case 4: /* verr */
7587
        case 5: /* verw */
7588
            if (!s->pe || s->vm86)
7589
                goto illegal_op;
7590
            gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
7591
            gen_update_cc_op(s);
7592
            if (op == 4) {
7593
                gen_helper_verr(cpu_env, cpu_T[0]);
7594
            } else {
7595
                gen_helper_verw(cpu_env, cpu_T[0]);
7596
            }
7597
            set_cc_op(s, CC_OP_EFLAGS);
7598
            break;
7599
        default:
7600
            goto illegal_op;
7601
        }
7602
        break;
7603
    case 0x101:
7604
        modrm = cpu_ldub_code(env, s->pc++);
7605
        mod = (modrm >> 6) & 3;
7606
        op = (modrm >> 3) & 7;
7607
        rm = modrm & 7;
7608
        switch(op) {
7609
        case 0: /* sgdt */
7610
            if (mod == 3)
7611
                goto illegal_op;
7612
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ);
7613
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7614
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.limit));
7615
            gen_op_st_T0_A0(OT_WORD + s->mem_index);
7616
            gen_add_A0_im(s, 2);
7617
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.base));
7618
            if (!s->dflag)
7619
                gen_op_andl_T0_im(0xffffff);
7620
            gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
7621
            break;
7622
        case 1:
7623
            if (mod == 3) {
7624
                switch (rm) {
7625
                case 0: /* monitor */
7626
                    if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
7627
                        s->cpl != 0)
7628
                        goto illegal_op;
7629
                    gen_update_cc_op(s);
7630
                    gen_jmp_im(pc_start - s->cs_base);
7631
#ifdef TARGET_X86_64
7632
                    if (s->aflag == 2) {
7633
                        gen_op_movq_A0_reg(R_EAX);
7634
                    } else
7635
#endif
7636
                    {
7637
                        gen_op_movl_A0_reg(R_EAX);
7638
                        if (s->aflag == 0)
7639
                            gen_op_andl_A0_ffff();
7640
                    }
7641
                    gen_add_A0_ds_seg(s);
7642
                    gen_helper_monitor(cpu_env, cpu_A0);
7643
                    break;
7644
                case 1: /* mwait */
7645
                    if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
7646
                        s->cpl != 0)
7647
                        goto illegal_op;
7648
                    gen_update_cc_op(s);
7649
                    gen_jmp_im(pc_start - s->cs_base);
7650
                    gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - pc_start));
7651
                    gen_eob(s);
7652
                    break;
7653
                case 2: /* clac */
7654
                    if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) ||
7655
                        s->cpl != 0) {
7656
                        goto illegal_op;
7657
                    }
7658
                    gen_helper_clac(cpu_env);
7659
                    gen_jmp_im(s->pc - s->cs_base);
7660
                    gen_eob(s);
7661
                    break;
7662
                case 3: /* stac */
7663
                    if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) ||
7664
                        s->cpl != 0) {
7665
                        goto illegal_op;
7666
                    }
7667
                    gen_helper_stac(cpu_env);
7668
                    gen_jmp_im(s->pc - s->cs_base);
7669
                    gen_eob(s);
7670
                    break;
7671
                default:
7672
                    goto illegal_op;
7673
                }
7674
            } else { /* sidt */
7675
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ);
7676
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7677
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.limit));
7678
                gen_op_st_T0_A0(OT_WORD + s->mem_index);
7679
                gen_add_A0_im(s, 2);
7680
                tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.base));
7681
                if (!s->dflag)
7682
                    gen_op_andl_T0_im(0xffffff);
7683
                gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
7684
            }
7685
            break;
7686
        case 2: /* lgdt */
7687
        case 3: /* lidt */
7688
            if (mod == 3) {
7689
                gen_update_cc_op(s);
7690
                gen_jmp_im(pc_start - s->cs_base);
7691
                switch(rm) {
7692
                case 0: /* VMRUN */
7693
                    if (!(s->flags & HF_SVME_MASK) || !s->pe)
7694
                        goto illegal_op;
7695
                    if (s->cpl != 0) {
7696
                        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7697
                        break;
7698
                    } else {
7699
                        gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag),
7700
                                         tcg_const_i32(s->pc - pc_start));
7701
                        tcg_gen_exit_tb(0);
7702
                        s->is_jmp = DISAS_TB_JUMP;
7703
                    }
7704
                    break;
7705
                case 1: /* VMMCALL */
7706
                    if (!(s->flags & HF_SVME_MASK))
7707
                        goto illegal_op;
7708
                    gen_helper_vmmcall(cpu_env);
7709
                    break;
7710
                case 2: /* VMLOAD */
7711
                    if (!(s->flags & HF_SVME_MASK) || !s->pe)
7712
                        goto illegal_op;
7713
                    if (s->cpl != 0) {
7714
                        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7715
                        break;
7716
                    } else {
7717
                        gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag));
7718
                    }
7719
                    break;
7720
                case 3: /* VMSAVE */
7721
                    if (!(s->flags & HF_SVME_MASK) || !s->pe)
7722
                        goto illegal_op;
7723
                    if (s->cpl != 0) {
7724
                        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7725
                        break;
7726
                    } else {
7727
                        gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag));
7728
                    }
7729
                    break;
7730
                case 4: /* STGI */
7731
                    if ((!(s->flags & HF_SVME_MASK) &&
7732
                         !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) || 
7733
                        !s->pe)
7734
                        goto illegal_op;
7735
                    if (s->cpl != 0) {
7736
                        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7737
                        break;
7738
                    } else {
7739
                        gen_helper_stgi(cpu_env);
7740
                    }
7741
                    break;
7742
                case 5: /* CLGI */
7743
                    if (!(s->flags & HF_SVME_MASK) || !s->pe)
7744
                        goto illegal_op;
7745
                    if (s->cpl != 0) {
7746
                        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7747
                        break;
7748
                    } else {
7749
                        gen_helper_clgi(cpu_env);
7750
                    }
7751
                    break;
7752
                case 6: /* SKINIT */
7753
                    if ((!(s->flags & HF_SVME_MASK) && 
7754
                         !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) || 
7755
                        !s->pe)
7756
                        goto illegal_op;
7757
                    gen_helper_skinit(cpu_env);
7758
                    break;
7759
                case 7: /* INVLPGA */
7760
                    if (!(s->flags & HF_SVME_MASK) || !s->pe)
7761
                        goto illegal_op;
7762
                    if (s->cpl != 0) {
7763
                        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7764
                        break;
7765
                    } else {
7766
                        gen_helper_invlpga(cpu_env, tcg_const_i32(s->aflag));
7767
                    }
7768
                    break;
7769
                default:
7770
                    goto illegal_op;
7771
                }
7772
            } else if (s->cpl != 0) {
7773
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7774
            } else {
7775
                gen_svm_check_intercept(s, pc_start,
7776
                                        op==2 ? SVM_EXIT_GDTR_WRITE : SVM_EXIT_IDTR_WRITE);
7777
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7778
                gen_op_ld_T1_A0(OT_WORD + s->mem_index);
7779
                gen_add_A0_im(s, 2);
7780
                gen_op_ld_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
7781
                if (!s->dflag)
7782
                    gen_op_andl_T0_im(0xffffff);
7783
                if (op == 2) {
7784
                    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,gdt.base));
7785
                    tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,gdt.limit));
7786
                } else {
7787
                    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,idt.base));
7788
                    tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,idt.limit));
7789
                }
7790
            }
7791
            break;
7792
        case 4: /* smsw */
7793
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
7794
#if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
7795
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]) + 4);
7796
#else
7797
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]));
7798
#endif
7799
            gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 1);
7800
            break;
7801
        case 6: /* lmsw */
7802
            if (s->cpl != 0) {
7803
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7804
            } else {
7805
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7806
                gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
7807
                gen_helper_lmsw(cpu_env, cpu_T[0]);
7808
                gen_jmp_im(s->pc - s->cs_base);
7809
                gen_eob(s);
7810
            }
7811
            break;
7812
        case 7:
7813
            if (mod != 3) { /* invlpg */
7814
                if (s->cpl != 0) {
7815
                    gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7816
                } else {
7817
                    gen_update_cc_op(s);
7818
                    gen_jmp_im(pc_start - s->cs_base);
7819
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7820
                    gen_helper_invlpg(cpu_env, cpu_A0);
7821
                    gen_jmp_im(s->pc - s->cs_base);
7822
                    gen_eob(s);
7823
                }
7824
            } else {
7825
                switch (rm) {
7826
                case 0: /* swapgs */
7827
#ifdef TARGET_X86_64
7828
                    if (CODE64(s)) {
7829
                        if (s->cpl != 0) {
7830
                            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7831
                        } else {
7832
                            tcg_gen_ld_tl(cpu_T[0], cpu_env,
7833
                                offsetof(CPUX86State,segs[R_GS].base));
7834
                            tcg_gen_ld_tl(cpu_T[1], cpu_env,
7835
                                offsetof(CPUX86State,kernelgsbase));
7836
                            tcg_gen_st_tl(cpu_T[1], cpu_env,
7837
                                offsetof(CPUX86State,segs[R_GS].base));
7838
                            tcg_gen_st_tl(cpu_T[0], cpu_env,
7839
                                offsetof(CPUX86State,kernelgsbase));
7840
                        }
7841
                    } else
7842
#endif
7843
                    {
7844
                        goto illegal_op;
7845
                    }
7846
                    break;
7847
                case 1: /* rdtscp */
7848
                    if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP))
7849
                        goto illegal_op;
7850
                    gen_update_cc_op(s);
7851
                    gen_jmp_im(pc_start - s->cs_base);
7852
                    if (use_icount)
7853
                        gen_io_start();
7854
                    gen_helper_rdtscp(cpu_env);
7855
                    if (use_icount) {
7856
                        gen_io_end();
7857
                        gen_jmp(s, s->pc - s->cs_base);
7858
                    }
7859
                    break;
7860
                default:
7861
                    goto illegal_op;
7862
                }
7863
            }
7864
            break;
7865
        default:
7866
            goto illegal_op;
7867
        }
7868
        break;
7869
    case 0x108: /* invd */
7870
    case 0x109: /* wbinvd */
7871
        if (s->cpl != 0) {
7872
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7873
        } else {
7874
            gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
7875
            /* nothing to do */
7876
        }
7877
        break;
7878
    case 0x63: /* arpl or movslS (x86_64) */
7879
#ifdef TARGET_X86_64
7880
        if (CODE64(s)) {
7881
            int d_ot;
7882
            /* d_ot is the size of destination */
7883
            d_ot = dflag + OT_WORD;
7884

    
7885
            modrm = cpu_ldub_code(env, s->pc++);
7886
            reg = ((modrm >> 3) & 7) | rex_r;
7887
            mod = (modrm >> 6) & 3;
7888
            rm = (modrm & 7) | REX_B(s);
7889

    
7890
            if (mod == 3) {
7891
                gen_op_mov_TN_reg(OT_LONG, 0, rm);
7892
                /* sign extend */
7893
                if (d_ot == OT_QUAD)
7894
                    tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
7895
                gen_op_mov_reg_T0(d_ot, reg);
7896
            } else {
7897
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7898
                if (d_ot == OT_QUAD) {
7899
                    gen_op_lds_T0_A0(OT_LONG + s->mem_index);
7900
                } else {
7901
                    gen_op_ld_T0_A0(OT_LONG + s->mem_index);
7902
                }
7903
                gen_op_mov_reg_T0(d_ot, reg);
7904
            }
7905
        } else
7906
#endif
7907
        {
7908
            int label1;
7909
            TCGv t0, t1, t2, a0;
7910

    
7911
            if (!s->pe || s->vm86)
7912
                goto illegal_op;
7913
            t0 = tcg_temp_local_new();
7914
            t1 = tcg_temp_local_new();
7915
            t2 = tcg_temp_local_new();
7916
            ot = OT_WORD;
7917
            modrm = cpu_ldub_code(env, s->pc++);
7918
            reg = (modrm >> 3) & 7;
7919
            mod = (modrm >> 6) & 3;
7920
            rm = modrm & 7;
7921
            if (mod != 3) {
7922
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7923
                gen_op_ld_v(ot + s->mem_index, t0, cpu_A0);
7924
                a0 = tcg_temp_local_new();
7925
                tcg_gen_mov_tl(a0, cpu_A0);
7926
            } else {
7927
                gen_op_mov_v_reg(ot, t0, rm);
7928
                TCGV_UNUSED(a0);
7929
            }
7930
            gen_op_mov_v_reg(ot, t1, reg);
7931
            tcg_gen_andi_tl(cpu_tmp0, t0, 3);
7932
            tcg_gen_andi_tl(t1, t1, 3);
7933
            tcg_gen_movi_tl(t2, 0);
7934
            label1 = gen_new_label();
7935
            tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, t1, label1);
7936
            tcg_gen_andi_tl(t0, t0, ~3);
7937
            tcg_gen_or_tl(t0, t0, t1);
7938
            tcg_gen_movi_tl(t2, CC_Z);
7939
            gen_set_label(label1);
7940
            if (mod != 3) {
7941
                gen_op_st_v(ot + s->mem_index, t0, a0);
7942
                tcg_temp_free(a0);
7943
           } else {
7944
                gen_op_mov_reg_v(ot, rm, t0);
7945
            }
7946
            gen_compute_eflags(s);
7947
            tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
7948
            tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
7949
            tcg_temp_free(t0);
7950
            tcg_temp_free(t1);
7951
            tcg_temp_free(t2);
7952
        }
7953
        break;
7954
    case 0x102: /* lar */
7955
    case 0x103: /* lsl */
7956
        {
7957
            int label1;
7958
            TCGv t0;
7959
            if (!s->pe || s->vm86)
7960
                goto illegal_op;
7961
            ot = dflag ? OT_LONG : OT_WORD;
7962
            modrm = cpu_ldub_code(env, s->pc++);
7963
            reg = ((modrm >> 3) & 7) | rex_r;
7964
            gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
7965
            t0 = tcg_temp_local_new();
7966
            gen_update_cc_op(s);
7967
            if (b == 0x102) {
7968
                gen_helper_lar(t0, cpu_env, cpu_T[0]);
7969
            } else {
7970
                gen_helper_lsl(t0, cpu_env, cpu_T[0]);
7971
            }
7972
            tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
7973
            label1 = gen_new_label();
7974
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
7975
            gen_op_mov_reg_v(ot, reg, t0);
7976
            gen_set_label(label1);
7977
            set_cc_op(s, CC_OP_EFLAGS);
7978
            tcg_temp_free(t0);
7979
        }
7980
        break;
7981
    case 0x118:
7982
        modrm = cpu_ldub_code(env, s->pc++);
7983
        mod = (modrm >> 6) & 3;
7984
        op = (modrm >> 3) & 7;
7985
        switch(op) {
7986
        case 0: /* prefetchnta */
7987
        case 1: /* prefetchnt0 */
7988
        case 2: /* prefetchnt0 */
7989
        case 3: /* prefetchnt0 */
7990
            if (mod == 3)
7991
                goto illegal_op;
7992
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7993
            /* nothing more to do */
7994
            break;
7995
        default: /* nop (multi byte) */
7996
            gen_nop_modrm(env, s, modrm);
7997
            break;
7998
        }
7999
        break;
8000
    case 0x119 ... 0x11f: /* nop (multi byte) */
8001
        modrm = cpu_ldub_code(env, s->pc++);
8002
        gen_nop_modrm(env, s, modrm);
8003
        break;
8004
    case 0x120: /* mov reg, crN */
8005
    case 0x122: /* mov crN, reg */
8006
        if (s->cpl != 0) {
8007
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
8008
        } else {
8009
            modrm = cpu_ldub_code(env, s->pc++);
8010
            /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8011
             * AMD documentation (24594.pdf) and testing of
8012
             * intel 386 and 486 processors all show that the mod bits
8013
             * are assumed to be 1's, regardless of actual values.
8014
             */
8015
            rm = (modrm & 7) | REX_B(s);
8016
            reg = ((modrm >> 3) & 7) | rex_r;
8017
            if (CODE64(s))
8018
                ot = OT_QUAD;
8019
            else
8020
                ot = OT_LONG;
8021
            if ((prefixes & PREFIX_LOCK) && (reg == 0) &&
8022
                (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
8023
                reg = 8;
8024
            }
8025
            switch(reg) {
8026
            case 0:
8027
            case 2:
8028
            case 3:
8029
            case 4:
8030
            case 8:
8031
                gen_update_cc_op(s);
8032
                gen_jmp_im(pc_start - s->cs_base);
8033
                if (b & 2) {
8034
                    gen_op_mov_TN_reg(ot, 0, rm);
8035
                    gen_helper_write_crN(cpu_env, tcg_const_i32(reg),
8036
                                         cpu_T[0]);
8037
                    gen_jmp_im(s->pc - s->cs_base);
8038
                    gen_eob(s);
8039
                } else {
8040
                    gen_helper_read_crN(cpu_T[0], cpu_env, tcg_const_i32(reg));
8041
                    gen_op_mov_reg_T0(ot, rm);
8042
                }
8043
                break;
8044
            default:
8045
                goto illegal_op;
8046
            }
8047
        }
8048
        break;
8049
    case 0x121: /* mov reg, drN */
8050
    case 0x123: /* mov drN, reg */
8051
        if (s->cpl != 0) {
8052
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
8053
        } else {
8054
            modrm = cpu_ldub_code(env, s->pc++);
8055
            /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8056
             * AMD documentation (24594.pdf) and testing of
8057
             * intel 386 and 486 processors all show that the mod bits
8058
             * are assumed to be 1's, regardless of actual values.
8059
             */
8060
            rm = (modrm & 7) | REX_B(s);
8061
            reg = ((modrm >> 3) & 7) | rex_r;
8062
            if (CODE64(s))
8063
                ot = OT_QUAD;
8064
            else
8065
                ot = OT_LONG;
8066
            /* XXX: do it dynamically with CR4.DE bit */
8067
            if (reg == 4 || reg == 5 || reg >= 8)
8068
                goto illegal_op;
8069
            if (b & 2) {
8070
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
8071
                gen_op_mov_TN_reg(ot, 0, rm);
8072
                gen_helper_movl_drN_T0(cpu_env, tcg_const_i32(reg), cpu_T[0]);
8073
                gen_jmp_im(s->pc - s->cs_base);
8074
                gen_eob(s);
8075
            } else {
8076
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
8077
                tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,dr[reg]));
8078
                gen_op_mov_reg_T0(ot, rm);
8079
            }
8080
        }
8081
        break;
8082
    case 0x106: /* clts */
8083
        if (s->cpl != 0) {
8084
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
8085
        } else {
8086
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
8087
            gen_helper_clts(cpu_env);
8088
            /* abort block because static cpu state changed */
8089
            gen_jmp_im(s->pc - s->cs_base);
8090
            gen_eob(s);
8091
        }
8092
        break;
8093
    /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
8094
    case 0x1c3: /* MOVNTI reg, mem */
8095
        if (!(s->cpuid_features & CPUID_SSE2))
8096
            goto illegal_op;
8097
        ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
8098
        modrm = cpu_ldub_code(env, s->pc++);
8099
        mod = (modrm >> 6) & 3;
8100
        if (mod == 3)
8101
            goto illegal_op;
8102
        reg = ((modrm >> 3) & 7) | rex_r;
8103
        /* generate a generic store */
8104
        gen_ldst_modrm(env, s, modrm, ot, reg, 1);
8105
        break;
8106
    case 0x1ae:
8107
        modrm = cpu_ldub_code(env, s->pc++);
8108
        mod = (modrm >> 6) & 3;
8109
        op = (modrm >> 3) & 7;
8110
        switch(op) {
8111
        case 0: /* fxsave */
8112
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
8113
                (s->prefix & PREFIX_LOCK))
8114
                goto illegal_op;
8115
            if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
8116
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8117
                break;
8118
            }
8119
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
8120
            gen_update_cc_op(s);
8121
            gen_jmp_im(pc_start - s->cs_base);
8122
            gen_helper_fxsave(cpu_env, cpu_A0, tcg_const_i32((s->dflag == 2)));
8123
            break;
8124
        case 1: /* fxrstor */
8125
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
8126
                (s->prefix & PREFIX_LOCK))
8127
                goto illegal_op;
8128
            if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
8129
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8130
                break;
8131
            }
8132
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
8133
            gen_update_cc_op(s);
8134
            gen_jmp_im(pc_start - s->cs_base);
8135
            gen_helper_fxrstor(cpu_env, cpu_A0,
8136
                               tcg_const_i32((s->dflag == 2)));
8137
            break;
8138
        case 2: /* ldmxcsr */
8139
        case 3: /* stmxcsr */
8140
            if (s->flags & HF_TS_MASK) {
8141
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8142
                break;
8143
            }
8144
            if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
8145
                mod == 3)
8146
                goto illegal_op;
8147
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
8148
            if (op == 2) {
8149
                gen_op_ld_T0_A0(OT_LONG + s->mem_index);
8150
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
8151
                gen_helper_ldmxcsr(cpu_env, cpu_tmp2_i32);
8152
            } else {
8153
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
8154
                gen_op_st_T0_A0(OT_LONG + s->mem_index);
8155
            }
8156
            break;
8157
        case 5: /* lfence */
8158
        case 6: /* mfence */
8159
            if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE2))
8160
                goto illegal_op;
8161
            break;
8162
        case 7: /* sfence / clflush */
8163
            if ((modrm & 0xc7) == 0xc0) {
8164
                /* sfence */
8165
                /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
8166
                if (!(s->cpuid_features & CPUID_SSE))
8167
                    goto illegal_op;
8168
            } else {
8169
                /* clflush */
8170
                if (!(s->cpuid_features & CPUID_CLFLUSH))
8171
                    goto illegal_op;
8172
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
8173
            }
8174
            break;
8175
        default:
8176
            goto illegal_op;
8177
        }
8178
        break;
8179
    case 0x10d: /* 3DNow! prefetch(w) */
8180
        modrm = cpu_ldub_code(env, s->pc++);
8181
        mod = (modrm >> 6) & 3;
8182
        if (mod == 3)
8183
            goto illegal_op;
8184
        gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
8185
        /* ignore for now */
8186
        break;
8187
    case 0x1aa: /* rsm */
8188
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
8189
        if (!(s->flags & HF_SMM_MASK))
8190
            goto illegal_op;
8191
        gen_update_cc_op(s);
8192
        gen_jmp_im(s->pc - s->cs_base);
8193
        gen_helper_rsm(cpu_env);
8194
        gen_eob(s);
8195
        break;
8196
    case 0x1b8: /* SSE4.2 popcnt */
8197
        if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
8198
             PREFIX_REPZ)
8199
            goto illegal_op;
8200
        if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
8201
            goto illegal_op;
8202

    
8203
        modrm = cpu_ldub_code(env, s->pc++);
8204
        reg = ((modrm >> 3) & 7) | rex_r;
8205

    
8206
        if (s->prefix & PREFIX_DATA)
8207
            ot = OT_WORD;
8208
        else if (s->dflag != 2)
8209
            ot = OT_LONG;
8210
        else
8211
            ot = OT_QUAD;
8212

    
8213
        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
8214
        gen_helper_popcnt(cpu_T[0], cpu_env, cpu_T[0], tcg_const_i32(ot));
8215
        gen_op_mov_reg_T0(ot, reg);
8216

    
8217
        set_cc_op(s, CC_OP_EFLAGS);
8218
        break;
8219
    case 0x10e ... 0x10f:
8220
        /* 3DNow! instructions, ignore prefixes */
8221
        s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
8222
    case 0x110 ... 0x117:
8223
    case 0x128 ... 0x12f:
8224
    case 0x138 ... 0x13a:
8225
    case 0x150 ... 0x179:
8226
    case 0x17c ... 0x17f:
8227
    case 0x1c2:
8228
    case 0x1c4 ... 0x1c6:
8229
    case 0x1d0 ... 0x1fe:
8230
        gen_sse(env, s, b, pc_start, rex_r);
8231
        break;
8232
    default:
8233
        goto illegal_op;
8234
    }
8235
    /* lock generation */
8236
    if (s->prefix & PREFIX_LOCK)
8237
        gen_helper_unlock();
8238
    return s->pc;
8239
 illegal_op:
8240
    if (s->prefix & PREFIX_LOCK)
8241
        gen_helper_unlock();
8242
    /* XXX: ensure that no lock was generated */
8243
    gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
8244
    return s->pc;
8245
}
8246

    
8247
void optimize_flags_init(void)
8248
{
8249
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8250
    cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0,
8251
                                       offsetof(CPUX86State, cc_op), "cc_op");
8252
    cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_dst),
8253
                                    "cc_dst");
8254
    cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_src),
8255
                                    "cc_src");
8256
    cpu_cc_src2 = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_src2),
8257
                                     "cc_src2");
8258

    
8259
#ifdef TARGET_X86_64
8260
    cpu_regs[R_EAX] = tcg_global_mem_new_i64(TCG_AREG0,
8261
                                             offsetof(CPUX86State, regs[R_EAX]), "rax");
8262
    cpu_regs[R_ECX] = tcg_global_mem_new_i64(TCG_AREG0,
8263
                                             offsetof(CPUX86State, regs[R_ECX]), "rcx");
8264
    cpu_regs[R_EDX] = tcg_global_mem_new_i64(TCG_AREG0,
8265
                                             offsetof(CPUX86State, regs[R_EDX]), "rdx");
8266
    cpu_regs[R_EBX] = tcg_global_mem_new_i64(TCG_AREG0,
8267
                                             offsetof(CPUX86State, regs[R_EBX]), "rbx");
8268
    cpu_regs[R_ESP] = tcg_global_mem_new_i64(TCG_AREG0,
8269
                                             offsetof(CPUX86State, regs[R_ESP]), "rsp");
8270
    cpu_regs[R_EBP] = tcg_global_mem_new_i64(TCG_AREG0,
8271
                                             offsetof(CPUX86State, regs[R_EBP]), "rbp");
8272
    cpu_regs[R_ESI] = tcg_global_mem_new_i64(TCG_AREG0,
8273
                                             offsetof(CPUX86State, regs[R_ESI]), "rsi");
8274
    cpu_regs[R_EDI] = tcg_global_mem_new_i64(TCG_AREG0,
8275
                                             offsetof(CPUX86State, regs[R_EDI]), "rdi");
8276
    cpu_regs[8] = tcg_global_mem_new_i64(TCG_AREG0,
8277
                                         offsetof(CPUX86State, regs[8]), "r8");
8278
    cpu_regs[9] = tcg_global_mem_new_i64(TCG_AREG0,
8279
                                          offsetof(CPUX86State, regs[9]), "r9");
8280
    cpu_regs[10] = tcg_global_mem_new_i64(TCG_AREG0,
8281
                                          offsetof(CPUX86State, regs[10]), "r10");
8282
    cpu_regs[11] = tcg_global_mem_new_i64(TCG_AREG0,
8283
                                          offsetof(CPUX86State, regs[11]), "r11");
8284
    cpu_regs[12] = tcg_global_mem_new_i64(TCG_AREG0,
8285
                                          offsetof(CPUX86State, regs[12]), "r12");
8286
    cpu_regs[13] = tcg_global_mem_new_i64(TCG_AREG0,
8287
                                          offsetof(CPUX86State, regs[13]), "r13");
8288
    cpu_regs[14] = tcg_global_mem_new_i64(TCG_AREG0,
8289
                                          offsetof(CPUX86State, regs[14]), "r14");
8290
    cpu_regs[15] = tcg_global_mem_new_i64(TCG_AREG0,
8291
                                          offsetof(CPUX86State, regs[15]), "r15");
8292
#else
8293
    cpu_regs[R_EAX] = tcg_global_mem_new_i32(TCG_AREG0,
8294
                                             offsetof(CPUX86State, regs[R_EAX]), "eax");
8295
    cpu_regs[R_ECX] = tcg_global_mem_new_i32(TCG_AREG0,
8296
                                             offsetof(CPUX86State, regs[R_ECX]), "ecx");
8297
    cpu_regs[R_EDX] = tcg_global_mem_new_i32(TCG_AREG0,
8298
                                             offsetof(CPUX86State, regs[R_EDX]), "edx");
8299
    cpu_regs[R_EBX] = tcg_global_mem_new_i32(TCG_AREG0,
8300
                                             offsetof(CPUX86State, regs[R_EBX]), "ebx");
8301
    cpu_regs[R_ESP] = tcg_global_mem_new_i32(TCG_AREG0,
8302
                                             offsetof(CPUX86State, regs[R_ESP]), "esp");
8303
    cpu_regs[R_EBP] = tcg_global_mem_new_i32(TCG_AREG0,
8304
                                             offsetof(CPUX86State, regs[R_EBP]), "ebp");
8305
    cpu_regs[R_ESI] = tcg_global_mem_new_i32(TCG_AREG0,
8306
                                             offsetof(CPUX86State, regs[R_ESI]), "esi");
8307
    cpu_regs[R_EDI] = tcg_global_mem_new_i32(TCG_AREG0,
8308
                                             offsetof(CPUX86State, regs[R_EDI]), "edi");
8309
#endif
8310

    
8311
    /* register helpers */
8312
#define GEN_HELPER 2
8313
#include "helper.h"
8314
}
8315

    
8316
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8317
   basic block 'tb'. If search_pc is TRUE, also generate PC
8318
   information for each intermediate instruction. */
8319
static inline void gen_intermediate_code_internal(CPUX86State *env,
8320
                                                  TranslationBlock *tb,
8321
                                                  int search_pc)
8322
{
8323
    DisasContext dc1, *dc = &dc1;
8324
    target_ulong pc_ptr;
8325
    uint16_t *gen_opc_end;
8326
    CPUBreakpoint *bp;
8327
    int j, lj;
8328
    uint64_t flags;
8329
    target_ulong pc_start;
8330
    target_ulong cs_base;
8331
    int num_insns;
8332
    int max_insns;
8333

    
8334
    /* generate intermediate code */
8335
    pc_start = tb->pc;
8336
    cs_base = tb->cs_base;
8337
    flags = tb->flags;
8338

    
8339
    dc->pe = (flags >> HF_PE_SHIFT) & 1;
8340
    dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
8341
    dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
8342
    dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
8343
    dc->f_st = 0;
8344
    dc->vm86 = (flags >> VM_SHIFT) & 1;
8345
    dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
8346
    dc->iopl = (flags >> IOPL_SHIFT) & 3;
8347
    dc->tf = (flags >> TF_SHIFT) & 1;
8348
    dc->singlestep_enabled = env->singlestep_enabled;
8349
    dc->cc_op = CC_OP_DYNAMIC;
8350
    dc->cc_op_dirty = false;
8351
    dc->cs_base = cs_base;
8352
    dc->tb = tb;
8353
    dc->popl_esp_hack = 0;
8354
    /* select memory access functions */
8355
    dc->mem_index = 0;
8356
    if (flags & HF_SOFTMMU_MASK) {
8357
        dc->mem_index = (cpu_mmu_index(env) + 1) << 2;
8358
    }
8359
    dc->cpuid_features = env->cpuid_features;
8360
    dc->cpuid_ext_features = env->cpuid_ext_features;
8361
    dc->cpuid_ext2_features = env->cpuid_ext2_features;
8362
    dc->cpuid_ext3_features = env->cpuid_ext3_features;
8363
    dc->cpuid_7_0_ebx_features = env->cpuid_7_0_ebx_features;
8364
#ifdef TARGET_X86_64
8365
    dc->lma = (flags >> HF_LMA_SHIFT) & 1;
8366
    dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
8367
#endif
8368
    dc->flags = flags;
8369
    dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
8370
                    (flags & HF_INHIBIT_IRQ_MASK)
8371
#ifndef CONFIG_SOFTMMU
8372
                    || (flags & HF_SOFTMMU_MASK)
8373
#endif
8374
                    );
8375
#if 0
8376
    /* check addseg logic */
8377
    if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
8378
        printf("ERROR addseg\n");
8379
#endif
8380

    
8381
    cpu_T[0] = tcg_temp_new();
8382
    cpu_T[1] = tcg_temp_new();
8383
    cpu_A0 = tcg_temp_new();
8384

    
8385
    cpu_tmp0 = tcg_temp_new();
8386
    cpu_tmp1_i64 = tcg_temp_new_i64();
8387
    cpu_tmp2_i32 = tcg_temp_new_i32();
8388
    cpu_tmp3_i32 = tcg_temp_new_i32();
8389
    cpu_tmp4 = tcg_temp_new();
8390
    cpu_tmp5 = tcg_temp_new();
8391
    cpu_ptr0 = tcg_temp_new_ptr();
8392
    cpu_ptr1 = tcg_temp_new_ptr();
8393
    cpu_cc_srcT = tcg_temp_local_new();
8394

    
8395
    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
8396

    
8397
    dc->is_jmp = DISAS_NEXT;
8398
    pc_ptr = pc_start;
8399
    lj = -1;
8400
    num_insns = 0;
8401
    max_insns = tb->cflags & CF_COUNT_MASK;
8402
    if (max_insns == 0)
8403
        max_insns = CF_COUNT_MASK;
8404

    
8405
    gen_icount_start();
8406
    for(;;) {
8407
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
8408
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
8409
                if (bp->pc == pc_ptr &&
8410
                    !((bp->flags & BP_CPU) && (tb->flags & HF_RF_MASK))) {
8411
                    gen_debug(dc, pc_ptr - dc->cs_base);
8412
                    break;
8413
                }
8414
            }
8415
        }
8416
        if (search_pc) {
8417
            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
8418
            if (lj < j) {
8419
                lj++;
8420
                while (lj < j)
8421
                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
8422
            }
8423
            tcg_ctx.gen_opc_pc[lj] = pc_ptr;
8424
            gen_opc_cc_op[lj] = dc->cc_op;
8425
            tcg_ctx.gen_opc_instr_start[lj] = 1;
8426
            tcg_ctx.gen_opc_icount[lj] = num_insns;
8427
        }
8428
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8429
            gen_io_start();
8430

    
8431
        pc_ptr = disas_insn(env, dc, pc_ptr);
8432
        num_insns++;
8433
        /* stop translation if indicated */
8434
        if (dc->is_jmp)
8435
            break;
8436
        /* if single step mode, we generate only one instruction and
8437
           generate an exception */
8438
        /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8439
           the flag and abort the translation to give the irqs a
8440
           change to be happen */
8441
        if (dc->tf || dc->singlestep_enabled ||
8442
            (flags & HF_INHIBIT_IRQ_MASK)) {
8443
            gen_jmp_im(pc_ptr - dc->cs_base);
8444
            gen_eob(dc);
8445
            break;
8446
        }
8447
        /* if too long translation, stop generation too */
8448
        if (tcg_ctx.gen_opc_ptr >= gen_opc_end ||
8449
            (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32) ||
8450
            num_insns >= max_insns) {
8451
            gen_jmp_im(pc_ptr - dc->cs_base);
8452
            gen_eob(dc);
8453
            break;
8454
        }
8455
        if (singlestep) {
8456
            gen_jmp_im(pc_ptr - dc->cs_base);
8457
            gen_eob(dc);
8458
            break;
8459
        }
8460
    }
8461
    if (tb->cflags & CF_LAST_IO)
8462
        gen_io_end();
8463
    gen_icount_end(tb, num_insns);
8464
    *tcg_ctx.gen_opc_ptr = INDEX_op_end;
8465
    /* we don't forget to fill the last values */
8466
    if (search_pc) {
8467
        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
8468
        lj++;
8469
        while (lj <= j)
8470
            tcg_ctx.gen_opc_instr_start[lj++] = 0;
8471
    }
8472

    
8473
#ifdef DEBUG_DISAS
8474
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8475
        int disas_flags;
8476
        qemu_log("----------------\n");
8477
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
8478
#ifdef TARGET_X86_64
8479
        if (dc->code64)
8480
            disas_flags = 2;
8481
        else
8482
#endif
8483
            disas_flags = !dc->code32;
8484
        log_target_disas(env, pc_start, pc_ptr - pc_start, disas_flags);
8485
        qemu_log("\n");
8486
    }
8487
#endif
8488

    
8489
    if (!search_pc) {
8490
        tb->size = pc_ptr - pc_start;
8491
        tb->icount = num_insns;
8492
    }
8493
}
8494

    
8495
void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
8496
{
8497
    gen_intermediate_code_internal(env, tb, 0);
8498
}
8499

    
8500
void gen_intermediate_code_pc(CPUX86State *env, TranslationBlock *tb)
8501
{
8502
    gen_intermediate_code_internal(env, tb, 1);
8503
}
8504

    
8505
void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, int pc_pos)
8506
{
8507
    int cc_op;
8508
#ifdef DEBUG_DISAS
8509
    if (qemu_loglevel_mask(CPU_LOG_TB_OP)) {
8510
        int i;
8511
        qemu_log("RESTORE:\n");
8512
        for(i = 0;i <= pc_pos; i++) {
8513
            if (tcg_ctx.gen_opc_instr_start[i]) {
8514
                qemu_log("0x%04x: " TARGET_FMT_lx "\n", i,
8515
                        tcg_ctx.gen_opc_pc[i]);
8516
            }
8517
        }
8518
        qemu_log("pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
8519
                pc_pos, tcg_ctx.gen_opc_pc[pc_pos] - tb->cs_base,
8520
                (uint32_t)tb->cs_base);
8521
    }
8522
#endif
8523
    env->eip = tcg_ctx.gen_opc_pc[pc_pos] - tb->cs_base;
8524
    cc_op = gen_opc_cc_op[pc_pos];
8525
    if (cc_op != CC_OP_DYNAMIC)
8526
        env->cc_op = cc_op;
8527
}