Statistics
| Branch: | Revision:

root / target-i386 / translate.c @ 436ff2d2

History | View | Annotate | Download (283.6 kB)

1
/*
2
 *  i386 translation
3
 *
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, 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
    [CC_OP_CLR] = 0,
217
};
218

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
323
#ifdef TARGET_X86_64
324

    
325
#define NB_OP_SIZES 4
326

    
327
#else /* !TARGET_X86_64 */
328

    
329
#define NB_OP_SIZES 3
330

    
331
#endif /* !TARGET_X86_64 */
332

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
907
    if (s->cc_op == CC_OP_EFLAGS) {
908
        return;
909
    }
910
    if (s->cc_op == CC_OP_CLR) {
911
        tcg_gen_movi_tl(cpu_cc_src, CC_Z);
912
        set_cc_op(s, CC_OP_EFLAGS);
913
        return;
914
    }
915

    
916
    TCGV_UNUSED(zero);
917
    dst = cpu_cc_dst;
918
    src1 = cpu_cc_src;
919
    src2 = cpu_cc_src2;
920

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

    
937
    gen_update_cc_op(s);
938
    gen_helper_cc_compute_all(cpu_cc_src, dst, src1, src2, cpu_cc_op);
939
    set_cc_op(s, CC_OP_EFLAGS);
940

    
941
    if (dead) {
942
        tcg_temp_free(zero);
943
    }
944
}
945

    
946
typedef struct CCPrepare {
947
    TCGCond cond;
948
    TCGv reg;
949
    TCGv reg2;
950
    target_ulong imm;
951
    target_ulong mask;
952
    bool use_reg2;
953
    bool no_setcond;
954
} CCPrepare;
955

    
956
/* compute eflags.C to reg */
957
static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
958
{
959
    TCGv t0, t1;
960
    int size, shift;
961

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

    
973
    case CC_OP_ADDB ... CC_OP_ADDQ:
974
        /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
975
        size = s->cc_op - CC_OP_ADDB;
976
        t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
977
        t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
978
    add_sub:
979
        return (CCPrepare) { .cond = TCG_COND_LTU, .reg = t0,
980
                             .reg2 = t1, .mask = -1, .use_reg2 = true };
981

    
982
    case CC_OP_LOGICB ... CC_OP_LOGICQ:
983
    case CC_OP_CLR:
984
        return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
985

    
986
    case CC_OP_INCB ... CC_OP_INCQ:
987
    case CC_OP_DECB ... CC_OP_DECQ:
988
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
989
                             .mask = -1, .no_setcond = true };
990

    
991
    case CC_OP_SHLB ... CC_OP_SHLQ:
992
        /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
993
        size = s->cc_op - CC_OP_SHLB;
994
        shift = (8 << size) - 1;
995
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
996
                             .mask = (target_ulong)1 << shift };
997

    
998
    case CC_OP_MULB ... CC_OP_MULQ:
999
        return (CCPrepare) { .cond = TCG_COND_NE,
1000
                             .reg = cpu_cc_src, .mask = -1 };
1001

    
1002
    case CC_OP_BMILGB ... CC_OP_BMILGQ:
1003
        size = s->cc_op - CC_OP_BMILGB;
1004
        t0 = gen_ext_tl(reg, cpu_cc_src, size, false);
1005
        return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
1006

    
1007
    case CC_OP_ADCX:
1008
    case CC_OP_ADCOX:
1009
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst,
1010
                             .mask = -1, .no_setcond = true };
1011

    
1012
    case CC_OP_EFLAGS:
1013
    case CC_OP_SARB ... CC_OP_SARQ:
1014
        /* CC_SRC & 1 */
1015
        return (CCPrepare) { .cond = TCG_COND_NE,
1016
                             .reg = cpu_cc_src, .mask = CC_C };
1017

    
1018
    default:
1019
       /* The need to compute only C from CC_OP_DYNAMIC is important
1020
          in efficiently implementing e.g. INC at the start of a TB.  */
1021
       gen_update_cc_op(s);
1022
       gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src,
1023
                               cpu_cc_src2, cpu_cc_op);
1024
       return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
1025
                            .mask = -1, .no_setcond = true };
1026
    }
1027
}
1028

    
1029
/* compute eflags.P to reg */
1030
static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg)
1031
{
1032
    gen_compute_eflags(s);
1033
    return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1034
                         .mask = CC_P };
1035
}
1036

    
1037
/* compute eflags.S to reg */
1038
static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg)
1039
{
1040
    switch (s->cc_op) {
1041
    case CC_OP_DYNAMIC:
1042
        gen_compute_eflags(s);
1043
        /* FALLTHRU */
1044
    case CC_OP_EFLAGS:
1045
    case CC_OP_ADCX:
1046
    case CC_OP_ADOX:
1047
    case CC_OP_ADCOX:
1048
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1049
                             .mask = CC_S };
1050
    case CC_OP_CLR:
1051
        return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
1052
    default:
1053
        {
1054
            int size = (s->cc_op - CC_OP_ADDB) & 3;
1055
            TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true);
1056
            return (CCPrepare) { .cond = TCG_COND_LT, .reg = t0, .mask = -1 };
1057
        }
1058
    }
1059
}
1060

    
1061
/* compute eflags.O to reg */
1062
static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg)
1063
{
1064
    switch (s->cc_op) {
1065
    case CC_OP_ADOX:
1066
    case CC_OP_ADCOX:
1067
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2,
1068
                             .mask = -1, .no_setcond = true };
1069
    case CC_OP_CLR:
1070
        return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
1071
    default:
1072
        gen_compute_eflags(s);
1073
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1074
                             .mask = CC_O };
1075
    }
1076
}
1077

    
1078
/* compute eflags.Z to reg */
1079
static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg)
1080
{
1081
    switch (s->cc_op) {
1082
    case CC_OP_DYNAMIC:
1083
        gen_compute_eflags(s);
1084
        /* FALLTHRU */
1085
    case CC_OP_EFLAGS:
1086
    case CC_OP_ADCX:
1087
    case CC_OP_ADOX:
1088
    case CC_OP_ADCOX:
1089
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1090
                             .mask = CC_Z };
1091
    case CC_OP_CLR:
1092
        return (CCPrepare) { .cond = TCG_COND_ALWAYS, .mask = -1 };
1093
    default:
1094
        {
1095
            int size = (s->cc_op - CC_OP_ADDB) & 3;
1096
            TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
1097
            return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
1098
        }
1099
    }
1100
}
1101

    
1102
/* perform a conditional store into register 'reg' according to jump opcode
1103
   value 'b'. In the fast case, T0 is guaranted not to be used. */
1104
static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
1105
{
1106
    int inv, jcc_op, size, cond;
1107
    CCPrepare cc;
1108
    TCGv t0;
1109

    
1110
    inv = b & 1;
1111
    jcc_op = (b >> 1) & 7;
1112

    
1113
    switch (s->cc_op) {
1114
    case CC_OP_SUBB ... CC_OP_SUBQ:
1115
        /* We optimize relational operators for the cmp/jcc case.  */
1116
        size = s->cc_op - CC_OP_SUBB;
1117
        switch (jcc_op) {
1118
        case JCC_BE:
1119
            tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
1120
            gen_extu(size, cpu_tmp4);
1121
            t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
1122
            cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = cpu_tmp4,
1123
                               .reg2 = t0, .mask = -1, .use_reg2 = true };
1124
            break;
1125

    
1126
        case JCC_L:
1127
            cond = TCG_COND_LT;
1128
            goto fast_jcc_l;
1129
        case JCC_LE:
1130
            cond = TCG_COND_LE;
1131
        fast_jcc_l:
1132
            tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
1133
            gen_exts(size, cpu_tmp4);
1134
            t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, true);
1135
            cc = (CCPrepare) { .cond = cond, .reg = cpu_tmp4,
1136
                               .reg2 = t0, .mask = -1, .use_reg2 = true };
1137
            break;
1138

    
1139
        default:
1140
            goto slow_jcc;
1141
        }
1142
        break;
1143

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

    
1193
    if (inv) {
1194
        cc.cond = tcg_invert_cond(cc.cond);
1195
    }
1196
    return cc;
1197
}
1198

    
1199
static void gen_setcc1(DisasContext *s, int b, TCGv reg)
1200
{
1201
    CCPrepare cc = gen_prepare_cc(s, b, reg);
1202

    
1203
    if (cc.no_setcond) {
1204
        if (cc.cond == TCG_COND_EQ) {
1205
            tcg_gen_xori_tl(reg, cc.reg, 1);
1206
        } else {
1207
            tcg_gen_mov_tl(reg, cc.reg);
1208
        }
1209
        return;
1210
    }
1211

    
1212
    if (cc.cond == TCG_COND_NE && !cc.use_reg2 && cc.imm == 0 &&
1213
        cc.mask != 0 && (cc.mask & (cc.mask - 1)) == 0) {
1214
        tcg_gen_shri_tl(reg, cc.reg, ctztl(cc.mask));
1215
        tcg_gen_andi_tl(reg, reg, 1);
1216
        return;
1217
    }
1218
    if (cc.mask != -1) {
1219
        tcg_gen_andi_tl(reg, cc.reg, cc.mask);
1220
        cc.reg = reg;
1221
    }
1222
    if (cc.use_reg2) {
1223
        tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1224
    } else {
1225
        tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm);
1226
    }
1227
}
1228

    
1229
static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg)
1230
{
1231
    gen_setcc1(s, JCC_B << 1, reg);
1232
}
1233

    
1234
/* generate a conditional jump to label 'l1' according to jump opcode
1235
   value 'b'. In the fast case, T0 is guaranted not to be used. */
1236
static inline void gen_jcc1_noeob(DisasContext *s, int b, int l1)
1237
{
1238
    CCPrepare cc = gen_prepare_cc(s, b, cpu_T[0]);
1239

    
1240
    if (cc.mask != -1) {
1241
        tcg_gen_andi_tl(cpu_T[0], cc.reg, cc.mask);
1242
        cc.reg = cpu_T[0];
1243
    }
1244
    if (cc.use_reg2) {
1245
        tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1246
    } else {
1247
        tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1248
    }
1249
}
1250

    
1251
/* Generate a conditional jump to label 'l1' according to jump opcode
1252
   value 'b'. In the fast case, T0 is guaranted not to be used.
1253
   A translation block must end soon.  */
1254
static inline void gen_jcc1(DisasContext *s, int b, int l1)
1255
{
1256
    CCPrepare cc = gen_prepare_cc(s, b, cpu_T[0]);
1257

    
1258
    gen_update_cc_op(s);
1259
    if (cc.mask != -1) {
1260
        tcg_gen_andi_tl(cpu_T[0], cc.reg, cc.mask);
1261
        cc.reg = cpu_T[0];
1262
    }
1263
    set_cc_op(s, CC_OP_DYNAMIC);
1264
    if (cc.use_reg2) {
1265
        tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1266
    } else {
1267
        tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1268
    }
1269
}
1270

    
1271
/* XXX: does not work with gdbstub "ice" single step - not a
1272
   serious problem */
1273
static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
1274
{
1275
    int l1, l2;
1276

    
1277
    l1 = gen_new_label();
1278
    l2 = gen_new_label();
1279
    gen_op_jnz_ecx(s->aflag, l1);
1280
    gen_set_label(l2);
1281
    gen_jmp_tb(s, next_eip, 1);
1282
    gen_set_label(l1);
1283
    return l2;
1284
}
1285

    
1286
static inline void gen_stos(DisasContext *s, int ot)
1287
{
1288
    gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
1289
    gen_string_movl_A0_EDI(s);
1290
    gen_op_st_T0_A0(ot + s->mem_index);
1291
    gen_op_movl_T0_Dshift(ot);
1292
    gen_op_add_reg_T0(s->aflag, R_EDI);
1293
}
1294

    
1295
static inline void gen_lods(DisasContext *s, int ot)
1296
{
1297
    gen_string_movl_A0_ESI(s);
1298
    gen_op_ld_T0_A0(ot + s->mem_index);
1299
    gen_op_mov_reg_T0(ot, R_EAX);
1300
    gen_op_movl_T0_Dshift(ot);
1301
    gen_op_add_reg_T0(s->aflag, R_ESI);
1302
}
1303

    
1304
static inline void gen_scas(DisasContext *s, int ot)
1305
{
1306
    gen_string_movl_A0_EDI(s);
1307
    gen_op_ld_T1_A0(ot + s->mem_index);
1308
    gen_op(s, OP_CMPL, ot, R_EAX);
1309
    gen_op_movl_T0_Dshift(ot);
1310
    gen_op_add_reg_T0(s->aflag, R_EDI);
1311
}
1312

    
1313
static inline void gen_cmps(DisasContext *s, int ot)
1314
{
1315
    gen_string_movl_A0_EDI(s);
1316
    gen_op_ld_T1_A0(ot + s->mem_index);
1317
    gen_string_movl_A0_ESI(s);
1318
    gen_op(s, OP_CMPL, ot, OR_TMP0);
1319
    gen_op_movl_T0_Dshift(ot);
1320
    gen_op_add_reg_T0(s->aflag, R_ESI);
1321
    gen_op_add_reg_T0(s->aflag, R_EDI);
1322
}
1323

    
1324
static inline void gen_ins(DisasContext *s, int ot)
1325
{
1326
    if (use_icount)
1327
        gen_io_start();
1328
    gen_string_movl_A0_EDI(s);
1329
    /* Note: we must do this dummy write first to be restartable in
1330
       case of page fault. */
1331
    gen_op_movl_T0_0();
1332
    gen_op_st_T0_A0(ot + s->mem_index);
1333
    gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
1334
    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
1335
    tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1336
    gen_helper_in_func(ot, cpu_T[0], cpu_tmp2_i32);
1337
    gen_op_st_T0_A0(ot + s->mem_index);
1338
    gen_op_movl_T0_Dshift(ot);
1339
    gen_op_add_reg_T0(s->aflag, R_EDI);
1340
    if (use_icount)
1341
        gen_io_end();
1342
}
1343

    
1344
static inline void gen_outs(DisasContext *s, int ot)
1345
{
1346
    if (use_icount)
1347
        gen_io_start();
1348
    gen_string_movl_A0_ESI(s);
1349
    gen_op_ld_T0_A0(ot + s->mem_index);
1350

    
1351
    gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
1352
    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
1353
    tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1354
    tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]);
1355
    gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
1356

    
1357
    gen_op_movl_T0_Dshift(ot);
1358
    gen_op_add_reg_T0(s->aflag, R_ESI);
1359
    if (use_icount)
1360
        gen_io_end();
1361
}
1362

    
1363
/* same method as Valgrind : we generate jumps to current or next
1364
   instruction */
1365
#define GEN_REPZ(op)                                                          \
1366
static inline void gen_repz_ ## op(DisasContext *s, int ot,                   \
1367
                                 target_ulong cur_eip, target_ulong next_eip) \
1368
{                                                                             \
1369
    int l2;\
1370
    gen_update_cc_op(s);                                                      \
1371
    l2 = gen_jz_ecx_string(s, next_eip);                                      \
1372
    gen_ ## op(s, ot);                                                        \
1373
    gen_op_add_reg_im(s->aflag, R_ECX, -1);                                   \
1374
    /* a loop would cause two single step exceptions if ECX = 1               \
1375
       before rep string_insn */                                              \
1376
    if (!s->jmp_opt)                                                          \
1377
        gen_op_jz_ecx(s->aflag, l2);                                          \
1378
    gen_jmp(s, cur_eip);                                                      \
1379
}
1380

    
1381
#define GEN_REPZ2(op)                                                         \
1382
static inline void gen_repz_ ## op(DisasContext *s, int ot,                   \
1383
                                   target_ulong cur_eip,                      \
1384
                                   target_ulong next_eip,                     \
1385
                                   int nz)                                    \
1386
{                                                                             \
1387
    int l2;\
1388
    gen_update_cc_op(s);                                                      \
1389
    l2 = gen_jz_ecx_string(s, next_eip);                                      \
1390
    gen_ ## op(s, ot);                                                        \
1391
    gen_op_add_reg_im(s->aflag, R_ECX, -1);                                   \
1392
    gen_update_cc_op(s);                                                      \
1393
    gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2);                                 \
1394
    if (!s->jmp_opt)                                                          \
1395
        gen_op_jz_ecx(s->aflag, l2);                                          \
1396
    gen_jmp(s, cur_eip);                                                      \
1397
}
1398

    
1399
GEN_REPZ(movs)
1400
GEN_REPZ(stos)
1401
GEN_REPZ(lods)
1402
GEN_REPZ(ins)
1403
GEN_REPZ(outs)
1404
GEN_REPZ2(scas)
1405
GEN_REPZ2(cmps)
1406

    
1407
static void gen_helper_fp_arith_ST0_FT0(int op)
1408
{
1409
    switch (op) {
1410
    case 0:
1411
        gen_helper_fadd_ST0_FT0(cpu_env);
1412
        break;
1413
    case 1:
1414
        gen_helper_fmul_ST0_FT0(cpu_env);
1415
        break;
1416
    case 2:
1417
        gen_helper_fcom_ST0_FT0(cpu_env);
1418
        break;
1419
    case 3:
1420
        gen_helper_fcom_ST0_FT0(cpu_env);
1421
        break;
1422
    case 4:
1423
        gen_helper_fsub_ST0_FT0(cpu_env);
1424
        break;
1425
    case 5:
1426
        gen_helper_fsubr_ST0_FT0(cpu_env);
1427
        break;
1428
    case 6:
1429
        gen_helper_fdiv_ST0_FT0(cpu_env);
1430
        break;
1431
    case 7:
1432
        gen_helper_fdivr_ST0_FT0(cpu_env);
1433
        break;
1434
    }
1435
}
1436

    
1437
/* NOTE the exception in "r" op ordering */
1438
static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1439
{
1440
    TCGv_i32 tmp = tcg_const_i32(opreg);
1441
    switch (op) {
1442
    case 0:
1443
        gen_helper_fadd_STN_ST0(cpu_env, tmp);
1444
        break;
1445
    case 1:
1446
        gen_helper_fmul_STN_ST0(cpu_env, tmp);
1447
        break;
1448
    case 4:
1449
        gen_helper_fsubr_STN_ST0(cpu_env, tmp);
1450
        break;
1451
    case 5:
1452
        gen_helper_fsub_STN_ST0(cpu_env, tmp);
1453
        break;
1454
    case 6:
1455
        gen_helper_fdivr_STN_ST0(cpu_env, tmp);
1456
        break;
1457
    case 7:
1458
        gen_helper_fdiv_STN_ST0(cpu_env, tmp);
1459
        break;
1460
    }
1461
}
1462

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

    
1550
/* if d == OR_TMP0, it means memory operand (address in A0) */
1551
static void gen_inc(DisasContext *s1, int ot, int d, int c)
1552
{
1553
    if (d != OR_TMP0)
1554
        gen_op_mov_TN_reg(ot, 0, d);
1555
    else
1556
        gen_op_ld_T0_A0(ot + s1->mem_index);
1557
    gen_compute_eflags_c(s1, cpu_cc_src);
1558
    if (c > 0) {
1559
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 1);
1560
        set_cc_op(s1, CC_OP_INCB + ot);
1561
    } else {
1562
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], -1);
1563
        set_cc_op(s1, CC_OP_DECB + ot);
1564
    }
1565
    if (d != OR_TMP0)
1566
        gen_op_mov_reg_T0(ot, d);
1567
    else
1568
        gen_op_st_T0_A0(ot + s1->mem_index);
1569
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1570
}
1571

    
1572
static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, 
1573
                            int is_right, int is_arith)
1574
{
1575
    target_ulong mask;
1576
    int shift_label;
1577
    TCGv t0, t1, t2;
1578

    
1579
    if (ot == OT_QUAD) {
1580
        mask = 0x3f;
1581
    } else {
1582
        mask = 0x1f;
1583
    }
1584

    
1585
    /* load */
1586
    if (op1 == OR_TMP0) {
1587
        gen_op_ld_T0_A0(ot + s->mem_index);
1588
    } else {
1589
        gen_op_mov_TN_reg(ot, 0, op1);
1590
    }
1591

    
1592
    t0 = tcg_temp_local_new();
1593
    t1 = tcg_temp_local_new();
1594
    t2 = tcg_temp_local_new();
1595

    
1596
    tcg_gen_andi_tl(t2, cpu_T[1], mask);
1597

    
1598
    if (is_right) {
1599
        if (is_arith) {
1600
            gen_exts(ot, cpu_T[0]);
1601
            tcg_gen_mov_tl(t0, cpu_T[0]);
1602
            tcg_gen_sar_tl(cpu_T[0], cpu_T[0], t2);
1603
        } else {
1604
            gen_extu(ot, cpu_T[0]);
1605
            tcg_gen_mov_tl(t0, cpu_T[0]);
1606
            tcg_gen_shr_tl(cpu_T[0], cpu_T[0], t2);
1607
        }
1608
    } else {
1609
        tcg_gen_mov_tl(t0, cpu_T[0]);
1610
        tcg_gen_shl_tl(cpu_T[0], cpu_T[0], t2);
1611
    }
1612

    
1613
    /* store */
1614
    if (op1 == OR_TMP0) {
1615
        gen_op_st_T0_A0(ot + s->mem_index);
1616
    } else {
1617
        gen_op_mov_reg_T0(ot, op1);
1618
    }
1619

    
1620
    /* Update eflags data because we cannot predict flags afterward.  */
1621
    gen_update_cc_op(s);
1622
    set_cc_op(s, CC_OP_DYNAMIC);
1623

    
1624
    tcg_gen_mov_tl(t1, cpu_T[0]);
1625

    
1626
    shift_label = gen_new_label();
1627
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, shift_label);
1628

    
1629
    tcg_gen_addi_tl(t2, t2, -1);
1630
    tcg_gen_mov_tl(cpu_cc_dst, t1);
1631

    
1632
    if (is_right) {
1633
        if (is_arith) {
1634
            tcg_gen_sar_tl(cpu_cc_src, t0, t2);
1635
        } else {
1636
            tcg_gen_shr_tl(cpu_cc_src, t0, t2);
1637
        }
1638
    } else {
1639
        tcg_gen_shl_tl(cpu_cc_src, t0, t2);
1640
    }
1641

    
1642
    if (is_right) {
1643
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
1644
    } else {
1645
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
1646
    }
1647

    
1648
    gen_set_label(shift_label);
1649

    
1650
    tcg_temp_free(t0);
1651
    tcg_temp_free(t1);
1652
    tcg_temp_free(t2);
1653
}
1654

    
1655
static void gen_shift_rm_im(DisasContext *s, int ot, int op1, int op2,
1656
                            int is_right, int is_arith)
1657
{
1658
    int mask;
1659
    
1660
    if (ot == OT_QUAD)
1661
        mask = 0x3f;
1662
    else
1663
        mask = 0x1f;
1664

    
1665
    /* load */
1666
    if (op1 == OR_TMP0)
1667
        gen_op_ld_T0_A0(ot + s->mem_index);
1668
    else
1669
        gen_op_mov_TN_reg(ot, 0, op1);
1670

    
1671
    op2 &= mask;
1672
    if (op2 != 0) {
1673
        if (is_right) {
1674
            if (is_arith) {
1675
                gen_exts(ot, cpu_T[0]);
1676
                tcg_gen_sari_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1677
                tcg_gen_sari_tl(cpu_T[0], cpu_T[0], op2);
1678
            } else {
1679
                gen_extu(ot, cpu_T[0]);
1680
                tcg_gen_shri_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1681
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], op2);
1682
            }
1683
        } else {
1684
            tcg_gen_shli_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1685
            tcg_gen_shli_tl(cpu_T[0], cpu_T[0], op2);
1686
        }
1687
    }
1688

    
1689
    /* store */
1690
    if (op1 == OR_TMP0)
1691
        gen_op_st_T0_A0(ot + s->mem_index);
1692
    else
1693
        gen_op_mov_reg_T0(ot, op1);
1694
        
1695
    /* update eflags if non zero shift */
1696
    if (op2 != 0) {
1697
        tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
1698
        tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1699
        set_cc_op(s, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1700
    }
1701
}
1702

    
1703
static inline void tcg_gen_lshift(TCGv ret, TCGv arg1, target_long arg2)
1704
{
1705
    if (arg2 >= 0)
1706
        tcg_gen_shli_tl(ret, arg1, arg2);
1707
    else
1708
        tcg_gen_shri_tl(ret, arg1, -arg2);
1709
}
1710

    
1711
static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, 
1712
                          int is_right)
1713
{
1714
    target_ulong mask;
1715
    int label1, label2, data_bits;
1716
    TCGv t0, t1, t2, a0;
1717

    
1718
    /* XXX: inefficient, but we must use local temps */
1719
    t0 = tcg_temp_local_new();
1720
    t1 = tcg_temp_local_new();
1721
    t2 = tcg_temp_local_new();
1722
    a0 = tcg_temp_local_new();
1723

    
1724
    if (ot == OT_QUAD)
1725
        mask = 0x3f;
1726
    else
1727
        mask = 0x1f;
1728

    
1729
    /* load */
1730
    if (op1 == OR_TMP0) {
1731
        tcg_gen_mov_tl(a0, cpu_A0);
1732
        gen_op_ld_v(ot + s->mem_index, t0, a0);
1733
    } else {
1734
        gen_op_mov_v_reg(ot, t0, op1);
1735
    }
1736

    
1737
    tcg_gen_mov_tl(t1, cpu_T[1]);
1738

    
1739
    tcg_gen_andi_tl(t1, t1, mask);
1740

    
1741
    /* Must test zero case to avoid using undefined behaviour in TCG
1742
       shifts. */
1743
    label1 = gen_new_label();
1744
    tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label1);
1745
    
1746
    if (ot <= OT_WORD)
1747
        tcg_gen_andi_tl(cpu_tmp0, t1, (1 << (3 + ot)) - 1);
1748
    else
1749
        tcg_gen_mov_tl(cpu_tmp0, t1);
1750
    
1751
    gen_extu(ot, t0);
1752
    tcg_gen_mov_tl(t2, t0);
1753

    
1754
    data_bits = 8 << ot;
1755
    /* XXX: rely on behaviour of shifts when operand 2 overflows (XXX:
1756
       fix TCG definition) */
1757
    if (is_right) {
1758
        tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp0);
1759
        tcg_gen_subfi_tl(cpu_tmp0, data_bits, cpu_tmp0);
1760
        tcg_gen_shl_tl(t0, t0, cpu_tmp0);
1761
    } else {
1762
        tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp0);
1763
        tcg_gen_subfi_tl(cpu_tmp0, data_bits, cpu_tmp0);
1764
        tcg_gen_shr_tl(t0, t0, cpu_tmp0);
1765
    }
1766
    tcg_gen_or_tl(t0, t0, cpu_tmp4);
1767

    
1768
    gen_set_label(label1);
1769
    /* store */
1770
    if (op1 == OR_TMP0) {
1771
        gen_op_st_v(ot + s->mem_index, t0, a0);
1772
    } else {
1773
        gen_op_mov_reg_v(ot, op1, t0);
1774
    }
1775
    
1776
    /* update eflags.  It is needed anyway most of the time, do it always.  */
1777
    gen_compute_eflags(s);
1778
    assert(s->cc_op == CC_OP_EFLAGS);
1779

    
1780
    label2 = gen_new_label();
1781
    tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label2);
1782

    
1783
    tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
1784
    tcg_gen_xor_tl(cpu_tmp0, t2, t0);
1785
    tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
1786
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
1787
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
1788
    if (is_right) {
1789
        tcg_gen_shri_tl(t0, t0, data_bits - 1);
1790
    }
1791
    tcg_gen_andi_tl(t0, t0, CC_C);
1792
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
1793

    
1794
    gen_set_label(label2);
1795

    
1796
    tcg_temp_free(t0);
1797
    tcg_temp_free(t1);
1798
    tcg_temp_free(t2);
1799
    tcg_temp_free(a0);
1800
}
1801

    
1802
static void gen_rot_rm_im(DisasContext *s, int ot, int op1, int op2,
1803
                          int is_right)
1804
{
1805
    int mask;
1806
    int data_bits;
1807
    TCGv t0, t1, a0;
1808

    
1809
    /* XXX: inefficient, but we must use local temps */
1810
    t0 = tcg_temp_local_new();
1811
    t1 = tcg_temp_local_new();
1812
    a0 = tcg_temp_local_new();
1813

    
1814
    if (ot == OT_QUAD)
1815
        mask = 0x3f;
1816
    else
1817
        mask = 0x1f;
1818

    
1819
    /* load */
1820
    if (op1 == OR_TMP0) {
1821
        tcg_gen_mov_tl(a0, cpu_A0);
1822
        gen_op_ld_v(ot + s->mem_index, t0, a0);
1823
    } else {
1824
        gen_op_mov_v_reg(ot, t0, op1);
1825
    }
1826

    
1827
    gen_extu(ot, t0);
1828
    tcg_gen_mov_tl(t1, t0);
1829

    
1830
    op2 &= mask;
1831
    data_bits = 8 << ot;
1832
    if (op2 != 0) {
1833
        int shift = op2 & ((1 << (3 + ot)) - 1);
1834
        if (is_right) {
1835
            tcg_gen_shri_tl(cpu_tmp4, t0, shift);
1836
            tcg_gen_shli_tl(t0, t0, data_bits - shift);
1837
        }
1838
        else {
1839
            tcg_gen_shli_tl(cpu_tmp4, t0, shift);
1840
            tcg_gen_shri_tl(t0, t0, data_bits - shift);
1841
        }
1842
        tcg_gen_or_tl(t0, t0, cpu_tmp4);
1843
    }
1844

    
1845
    /* store */
1846
    if (op1 == OR_TMP0) {
1847
        gen_op_st_v(ot + s->mem_index, t0, a0);
1848
    } else {
1849
        gen_op_mov_reg_v(ot, op1, t0);
1850
    }
1851

    
1852
    if (op2 != 0) {
1853
        /* update eflags */
1854
        gen_compute_eflags(s);
1855
        assert(s->cc_op == CC_OP_EFLAGS);
1856

    
1857
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
1858
        tcg_gen_xor_tl(cpu_tmp0, t1, t0);
1859
        tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
1860
        tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
1861
        tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
1862
        if (is_right) {
1863
            tcg_gen_shri_tl(t0, t0, data_bits - 1);
1864
        }
1865
        tcg_gen_andi_tl(t0, t0, CC_C);
1866
        tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
1867
    }
1868

    
1869
    tcg_temp_free(t0);
1870
    tcg_temp_free(t1);
1871
    tcg_temp_free(a0);
1872
}
1873

    
1874
/* XXX: add faster immediate = 1 case */
1875
static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, 
1876
                           int is_right)
1877
{
1878
    gen_compute_eflags(s);
1879
    assert(s->cc_op == CC_OP_EFLAGS);
1880

    
1881
    /* load */
1882
    if (op1 == OR_TMP0)
1883
        gen_op_ld_T0_A0(ot + s->mem_index);
1884
    else
1885
        gen_op_mov_TN_reg(ot, 0, op1);
1886
    
1887
    if (is_right) {
1888
        switch (ot) {
1889
        case OT_BYTE:
1890
            gen_helper_rcrb(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1891
            break;
1892
        case OT_WORD:
1893
            gen_helper_rcrw(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1894
            break;
1895
        case OT_LONG:
1896
            gen_helper_rcrl(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1897
            break;
1898
#ifdef TARGET_X86_64
1899
        case OT_QUAD:
1900
            gen_helper_rcrq(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1901
            break;
1902
#endif
1903
        }
1904
    } else {
1905
        switch (ot) {
1906
        case OT_BYTE:
1907
            gen_helper_rclb(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1908
            break;
1909
        case OT_WORD:
1910
            gen_helper_rclw(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1911
            break;
1912
        case OT_LONG:
1913
            gen_helper_rcll(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1914
            break;
1915
#ifdef TARGET_X86_64
1916
        case OT_QUAD:
1917
            gen_helper_rclq(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1918
            break;
1919
#endif
1920
        }
1921
    }
1922
    /* store */
1923
    if (op1 == OR_TMP0)
1924
        gen_op_st_T0_A0(ot + s->mem_index);
1925
    else
1926
        gen_op_mov_reg_T0(ot, op1);
1927
}
1928

    
1929
/* XXX: add faster immediate case */
1930
static void gen_shiftd_rm_T1(DisasContext *s, int ot, int op1,
1931
                             int is_right, TCGv count)
1932
{
1933
    int label1, label2, data_bits;
1934
    target_ulong mask;
1935
    TCGv t0, t1, t2, a0;
1936

    
1937
    t0 = tcg_temp_local_new();
1938
    t1 = tcg_temp_local_new();
1939
    t2 = tcg_temp_local_new();
1940
    a0 = tcg_temp_local_new();
1941

    
1942
    if (ot == OT_QUAD)
1943
        mask = 0x3f;
1944
    else
1945
        mask = 0x1f;
1946

    
1947
    /* load */
1948
    if (op1 == OR_TMP0) {
1949
        tcg_gen_mov_tl(a0, cpu_A0);
1950
        gen_op_ld_v(ot + s->mem_index, t0, a0);
1951
    } else {
1952
        gen_op_mov_v_reg(ot, t0, op1);
1953
    }
1954

    
1955
    tcg_gen_andi_tl(t2, count, mask);
1956
    tcg_gen_mov_tl(t1, cpu_T[1]);
1957

    
1958
    /* Must test zero case to avoid using undefined behaviour in TCG
1959
       shifts. */
1960
    label1 = gen_new_label();
1961
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
1962
    
1963
    tcg_gen_addi_tl(cpu_tmp5, t2, -1);
1964
    if (ot == OT_WORD) {
1965
        /* Note: we implement the Intel behaviour for shift count > 16 */
1966
        if (is_right) {
1967
            tcg_gen_andi_tl(t0, t0, 0xffff);
1968
            tcg_gen_shli_tl(cpu_tmp0, t1, 16);
1969
            tcg_gen_or_tl(t0, t0, cpu_tmp0);
1970
            tcg_gen_ext32u_tl(t0, t0);
1971

    
1972
            tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
1973
            
1974
            /* only needed if count > 16, but a test would complicate */
1975
            tcg_gen_subfi_tl(cpu_tmp5, 32, t2);
1976
            tcg_gen_shl_tl(cpu_tmp0, t0, cpu_tmp5);
1977

    
1978
            tcg_gen_shr_tl(t0, t0, t2);
1979

    
1980
            tcg_gen_or_tl(t0, t0, cpu_tmp0);
1981
        } else {
1982
            /* XXX: not optimal */
1983
            tcg_gen_andi_tl(t0, t0, 0xffff);
1984
            tcg_gen_shli_tl(t1, t1, 16);
1985
            tcg_gen_or_tl(t1, t1, t0);
1986
            tcg_gen_ext32u_tl(t1, t1);
1987
            
1988
            tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
1989
            tcg_gen_subfi_tl(cpu_tmp0, 32, cpu_tmp5);
1990
            tcg_gen_shr_tl(cpu_tmp5, t1, cpu_tmp0);
1991
            tcg_gen_or_tl(cpu_tmp4, cpu_tmp4, cpu_tmp5);
1992

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

    
2004
            tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
2005

    
2006
            tcg_gen_shr_tl(t0, t0, t2);
2007
            tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2);
2008
            tcg_gen_shl_tl(t1, t1, cpu_tmp5);
2009
            tcg_gen_or_tl(t0, t0, t1);
2010
            
2011
        } else {
2012
            if (ot == OT_LONG)
2013
                tcg_gen_ext32u_tl(t1, t1);
2014

    
2015
            tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
2016
            
2017
            tcg_gen_shl_tl(t0, t0, t2);
2018
            tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2);
2019
            tcg_gen_shr_tl(t1, t1, cpu_tmp5);
2020
            tcg_gen_or_tl(t0, t0, t1);
2021
        }
2022
    }
2023
    tcg_gen_mov_tl(t1, cpu_tmp4);
2024

    
2025
    gen_set_label(label1);
2026
    /* store */
2027
    if (op1 == OR_TMP0) {
2028
        gen_op_st_v(ot + s->mem_index, t0, a0);
2029
    } else {
2030
        gen_op_mov_reg_v(ot, op1, t0);
2031
    }
2032
    
2033
    /* Update eflags data because we cannot predict flags afterward.  */
2034
    gen_update_cc_op(s);
2035
    set_cc_op(s, CC_OP_DYNAMIC);
2036

    
2037
    label2 = gen_new_label();
2038
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label2);
2039

    
2040
    tcg_gen_mov_tl(cpu_cc_src, t1);
2041
    tcg_gen_mov_tl(cpu_cc_dst, t0);
2042
    if (is_right) {
2043
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
2044
    } else {
2045
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
2046
    }
2047
    gen_set_label(label2);
2048

    
2049
    tcg_temp_free(t0);
2050
    tcg_temp_free(t1);
2051
    tcg_temp_free(t2);
2052
    tcg_temp_free(a0);
2053
}
2054

    
2055
static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
2056
{
2057
    if (s != OR_TMP1)
2058
        gen_op_mov_TN_reg(ot, 1, s);
2059
    switch(op) {
2060
    case OP_ROL:
2061
        gen_rot_rm_T1(s1, ot, d, 0);
2062
        break;
2063
    case OP_ROR:
2064
        gen_rot_rm_T1(s1, ot, d, 1);
2065
        break;
2066
    case OP_SHL:
2067
    case OP_SHL1:
2068
        gen_shift_rm_T1(s1, ot, d, 0, 0);
2069
        break;
2070
    case OP_SHR:
2071
        gen_shift_rm_T1(s1, ot, d, 1, 0);
2072
        break;
2073
    case OP_SAR:
2074
        gen_shift_rm_T1(s1, ot, d, 1, 1);
2075
        break;
2076
    case OP_RCL:
2077
        gen_rotc_rm_T1(s1, ot, d, 0);
2078
        break;
2079
    case OP_RCR:
2080
        gen_rotc_rm_T1(s1, ot, d, 1);
2081
        break;
2082
    }
2083
}
2084

    
2085
static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
2086
{
2087
    switch(op) {
2088
    case OP_ROL:
2089
        gen_rot_rm_im(s1, ot, d, c, 0);
2090
        break;
2091
    case OP_ROR:
2092
        gen_rot_rm_im(s1, ot, d, c, 1);
2093
        break;
2094
    case OP_SHL:
2095
    case OP_SHL1:
2096
        gen_shift_rm_im(s1, ot, d, c, 0, 0);
2097
        break;
2098
    case OP_SHR:
2099
        gen_shift_rm_im(s1, ot, d, c, 1, 0);
2100
        break;
2101
    case OP_SAR:
2102
        gen_shift_rm_im(s1, ot, d, c, 1, 1);
2103
        break;
2104
    default:
2105
        /* currently not optimized */
2106
        gen_op_movl_T1_im(c);
2107
        gen_shift(s1, op, ot, d, OR_TMP1);
2108
        break;
2109
    }
2110
}
2111

    
2112
static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm,
2113
                          int *reg_ptr, int *offset_ptr)
2114
{
2115
    target_long disp;
2116
    int havesib;
2117
    int base;
2118
    int index;
2119
    int scale;
2120
    int opreg;
2121
    int mod, rm, code, override, must_add_seg;
2122

    
2123
    override = s->override;
2124
    must_add_seg = s->addseg;
2125
    if (override >= 0)
2126
        must_add_seg = 1;
2127
    mod = (modrm >> 6) & 3;
2128
    rm = modrm & 7;
2129

    
2130
    if (s->aflag) {
2131

    
2132
        havesib = 0;
2133
        base = rm;
2134
        index = 0;
2135
        scale = 0;
2136

    
2137
        if (base == 4) {
2138
            havesib = 1;
2139
            code = cpu_ldub_code(env, s->pc++);
2140
            scale = (code >> 6) & 3;
2141
            index = ((code >> 3) & 7) | REX_X(s);
2142
            base = (code & 7);
2143
        }
2144
        base |= REX_B(s);
2145

    
2146
        switch (mod) {
2147
        case 0:
2148
            if ((base & 7) == 5) {
2149
                base = -1;
2150
                disp = (int32_t)cpu_ldl_code(env, s->pc);
2151
                s->pc += 4;
2152
                if (CODE64(s) && !havesib) {
2153
                    disp += s->pc + s->rip_offset;
2154
                }
2155
            } else {
2156
                disp = 0;
2157
            }
2158
            break;
2159
        case 1:
2160
            disp = (int8_t)cpu_ldub_code(env, s->pc++);
2161
            break;
2162
        default:
2163
        case 2:
2164
            disp = (int32_t)cpu_ldl_code(env, s->pc);
2165
            s->pc += 4;
2166
            break;
2167
        }
2168

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

    
2291
    opreg = OR_A0;
2292
    disp = 0;
2293
    *reg_ptr = opreg;
2294
    *offset_ptr = disp;
2295
}
2296

    
2297
static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
2298
{
2299
    int mod, rm, base, code;
2300

    
2301
    mod = (modrm >> 6) & 3;
2302
    if (mod == 3)
2303
        return;
2304
    rm = modrm & 7;
2305

    
2306
    if (s->aflag) {
2307

    
2308
        base = rm;
2309

    
2310
        if (base == 4) {
2311
            code = cpu_ldub_code(env, s->pc++);
2312
            base = (code & 7);
2313
        }
2314

    
2315
        switch (mod) {
2316
        case 0:
2317
            if (base == 5) {
2318
                s->pc += 4;
2319
            }
2320
            break;
2321
        case 1:
2322
            s->pc++;
2323
            break;
2324
        default:
2325
        case 2:
2326
            s->pc += 4;
2327
            break;
2328
        }
2329
    } else {
2330
        switch (mod) {
2331
        case 0:
2332
            if (rm == 6) {
2333
                s->pc += 2;
2334
            }
2335
            break;
2336
        case 1:
2337
            s->pc++;
2338
            break;
2339
        default:
2340
        case 2:
2341
            s->pc += 2;
2342
            break;
2343
        }
2344
    }
2345
}
2346

    
2347
/* used for LEA and MOV AX, mem */
2348
static void gen_add_A0_ds_seg(DisasContext *s)
2349
{
2350
    int override, must_add_seg;
2351
    must_add_seg = s->addseg;
2352
    override = R_DS;
2353
    if (s->override >= 0) {
2354
        override = s->override;
2355
        must_add_seg = 1;
2356
    }
2357
    if (must_add_seg) {
2358
#ifdef TARGET_X86_64
2359
        if (CODE64(s)) {
2360
            gen_op_addq_A0_seg(override);
2361
        } else
2362
#endif
2363
        {
2364
            gen_op_addl_A0_seg(s, override);
2365
        }
2366
    }
2367
}
2368

    
2369
/* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2370
   OR_TMP0 */
2371
static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm,
2372
                           int ot, int reg, int is_store)
2373
{
2374
    int mod, rm, opreg, disp;
2375

    
2376
    mod = (modrm >> 6) & 3;
2377
    rm = (modrm & 7) | REX_B(s);
2378
    if (mod == 3) {
2379
        if (is_store) {
2380
            if (reg != OR_TMP0)
2381
                gen_op_mov_TN_reg(ot, 0, reg);
2382
            gen_op_mov_reg_T0(ot, rm);
2383
        } else {
2384
            gen_op_mov_TN_reg(ot, 0, rm);
2385
            if (reg != OR_TMP0)
2386
                gen_op_mov_reg_T0(ot, reg);
2387
        }
2388
    } else {
2389
        gen_lea_modrm(env, s, modrm, &opreg, &disp);
2390
        if (is_store) {
2391
            if (reg != OR_TMP0)
2392
                gen_op_mov_TN_reg(ot, 0, reg);
2393
            gen_op_st_T0_A0(ot + s->mem_index);
2394
        } else {
2395
            gen_op_ld_T0_A0(ot + s->mem_index);
2396
            if (reg != OR_TMP0)
2397
                gen_op_mov_reg_T0(ot, reg);
2398
        }
2399
    }
2400
}
2401

    
2402
static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, int ot)
2403
{
2404
    uint32_t ret;
2405

    
2406
    switch(ot) {
2407
    case OT_BYTE:
2408
        ret = cpu_ldub_code(env, s->pc);
2409
        s->pc++;
2410
        break;
2411
    case OT_WORD:
2412
        ret = cpu_lduw_code(env, s->pc);
2413
        s->pc += 2;
2414
        break;
2415
    default:
2416
    case OT_LONG:
2417
        ret = cpu_ldl_code(env, s->pc);
2418
        s->pc += 4;
2419
        break;
2420
    }
2421
    return ret;
2422
}
2423

    
2424
static inline int insn_const_size(unsigned int ot)
2425
{
2426
    if (ot <= OT_LONG)
2427
        return 1 << ot;
2428
    else
2429
        return 4;
2430
}
2431

    
2432
static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
2433
{
2434
    TranslationBlock *tb;
2435
    target_ulong pc;
2436

    
2437
    pc = s->cs_base + eip;
2438
    tb = s->tb;
2439
    /* NOTE: we handle the case where the TB spans two pages here */
2440
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
2441
        (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
2442
        /* jump to same page: we can use a direct jump */
2443
        tcg_gen_goto_tb(tb_num);
2444
        gen_jmp_im(eip);
2445
        tcg_gen_exit_tb((tcg_target_long)tb + tb_num);
2446
    } else {
2447
        /* jump to another page: currently not optimized */
2448
        gen_jmp_im(eip);
2449
        gen_eob(s);
2450
    }
2451
}
2452

    
2453
static inline void gen_jcc(DisasContext *s, int b,
2454
                           target_ulong val, target_ulong next_eip)
2455
{
2456
    int l1, l2;
2457

    
2458
    if (s->jmp_opt) {
2459
        l1 = gen_new_label();
2460
        gen_jcc1(s, b, l1);
2461

    
2462
        gen_goto_tb(s, 0, next_eip);
2463

    
2464
        gen_set_label(l1);
2465
        gen_goto_tb(s, 1, val);
2466
        s->is_jmp = DISAS_TB_JUMP;
2467
    } else {
2468
        l1 = gen_new_label();
2469
        l2 = gen_new_label();
2470
        gen_jcc1(s, b, l1);
2471

    
2472
        gen_jmp_im(next_eip);
2473
        tcg_gen_br(l2);
2474

    
2475
        gen_set_label(l1);
2476
        gen_jmp_im(val);
2477
        gen_set_label(l2);
2478
        gen_eob(s);
2479
    }
2480
}
2481

    
2482
static void gen_cmovcc1(CPUX86State *env, DisasContext *s, int ot, int b,
2483
                        int modrm, int reg)
2484
{
2485
    CCPrepare cc;
2486

    
2487
    gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
2488

    
2489
    cc = gen_prepare_cc(s, b, cpu_T[1]);
2490
    if (cc.mask != -1) {
2491
        TCGv t0 = tcg_temp_new();
2492
        tcg_gen_andi_tl(t0, cc.reg, cc.mask);
2493
        cc.reg = t0;
2494
    }
2495
    if (!cc.use_reg2) {
2496
        cc.reg2 = tcg_const_tl(cc.imm);
2497
    }
2498

    
2499
    tcg_gen_movcond_tl(cc.cond, cpu_T[0], cc.reg, cc.reg2,
2500
                       cpu_T[0], cpu_regs[reg]);
2501
    gen_op_mov_reg_T0(ot, reg);
2502

    
2503
    if (cc.mask != -1) {
2504
        tcg_temp_free(cc.reg);
2505
    }
2506
    if (!cc.use_reg2) {
2507
        tcg_temp_free(cc.reg2);
2508
    }
2509
}
2510

    
2511
static inline void gen_op_movl_T0_seg(int seg_reg)
2512
{
2513
    tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
2514
                     offsetof(CPUX86State,segs[seg_reg].selector));
2515
}
2516

    
2517
static inline void gen_op_movl_seg_T0_vm(int seg_reg)
2518
{
2519
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
2520
    tcg_gen_st32_tl(cpu_T[0], cpu_env, 
2521
                    offsetof(CPUX86State,segs[seg_reg].selector));
2522
    tcg_gen_shli_tl(cpu_T[0], cpu_T[0], 4);
2523
    tcg_gen_st_tl(cpu_T[0], cpu_env, 
2524
                  offsetof(CPUX86State,segs[seg_reg].base));
2525
}
2526

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

    
2550
static inline int svm_is_rep(int prefixes)
2551
{
2552
    return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
2553
}
2554

    
2555
static inline void
2556
gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2557
                              uint32_t type, uint64_t param)
2558
{
2559
    /* no SVM activated; fast case */
2560
    if (likely(!(s->flags & HF_SVMI_MASK)))
2561
        return;
2562
    gen_update_cc_op(s);
2563
    gen_jmp_im(pc_start - s->cs_base);
2564
    gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type),
2565
                                         tcg_const_i64(param));
2566
}
2567

    
2568
static inline void
2569
gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
2570
{
2571
    gen_svm_check_intercept_param(s, pc_start, type, 0);
2572
}
2573

    
2574
static inline void gen_stack_update(DisasContext *s, int addend)
2575
{
2576
#ifdef TARGET_X86_64
2577
    if (CODE64(s)) {
2578
        gen_op_add_reg_im(2, R_ESP, addend);
2579
    } else
2580
#endif
2581
    if (s->ss32) {
2582
        gen_op_add_reg_im(1, R_ESP, addend);
2583
    } else {
2584
        gen_op_add_reg_im(0, R_ESP, addend);
2585
    }
2586
}
2587

    
2588
/* generate a push. It depends on ss32, addseg and dflag */
2589
static void gen_push_T0(DisasContext *s)
2590
{
2591
#ifdef TARGET_X86_64
2592
    if (CODE64(s)) {
2593
        gen_op_movq_A0_reg(R_ESP);
2594
        if (s->dflag) {
2595
            gen_op_addq_A0_im(-8);
2596
            gen_op_st_T0_A0(OT_QUAD + s->mem_index);
2597
        } else {
2598
            gen_op_addq_A0_im(-2);
2599
            gen_op_st_T0_A0(OT_WORD + s->mem_index);
2600
        }
2601
        gen_op_mov_reg_A0(2, R_ESP);
2602
    } else
2603
#endif
2604
    {
2605
        gen_op_movl_A0_reg(R_ESP);
2606
        if (!s->dflag)
2607
            gen_op_addl_A0_im(-2);
2608
        else
2609
            gen_op_addl_A0_im(-4);
2610
        if (s->ss32) {
2611
            if (s->addseg) {
2612
                tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2613
                gen_op_addl_A0_seg(s, R_SS);
2614
            }
2615
        } else {
2616
            gen_op_andl_A0_ffff();
2617
            tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2618
            gen_op_addl_A0_seg(s, R_SS);
2619
        }
2620
        gen_op_st_T0_A0(s->dflag + 1 + s->mem_index);
2621
        if (s->ss32 && !s->addseg)
2622
            gen_op_mov_reg_A0(1, R_ESP);
2623
        else
2624
            gen_op_mov_reg_T1(s->ss32 + 1, R_ESP);
2625
    }
2626
}
2627

    
2628
/* generate a push. It depends on ss32, addseg and dflag */
2629
/* slower version for T1, only used for call Ev */
2630
static void gen_push_T1(DisasContext *s)
2631
{
2632
#ifdef TARGET_X86_64
2633
    if (CODE64(s)) {
2634
        gen_op_movq_A0_reg(R_ESP);
2635
        if (s->dflag) {
2636
            gen_op_addq_A0_im(-8);
2637
            gen_op_st_T1_A0(OT_QUAD + s->mem_index);
2638
        } else {
2639
            gen_op_addq_A0_im(-2);
2640
            gen_op_st_T0_A0(OT_WORD + s->mem_index);
2641
        }
2642
        gen_op_mov_reg_A0(2, R_ESP);
2643
    } else
2644
#endif
2645
    {
2646
        gen_op_movl_A0_reg(R_ESP);
2647
        if (!s->dflag)
2648
            gen_op_addl_A0_im(-2);
2649
        else
2650
            gen_op_addl_A0_im(-4);
2651
        if (s->ss32) {
2652
            if (s->addseg) {
2653
                gen_op_addl_A0_seg(s, R_SS);
2654
            }
2655
        } else {
2656
            gen_op_andl_A0_ffff();
2657
            gen_op_addl_A0_seg(s, R_SS);
2658
        }
2659
        gen_op_st_T1_A0(s->dflag + 1 + s->mem_index);
2660

    
2661
        if (s->ss32 && !s->addseg)
2662
            gen_op_mov_reg_A0(1, R_ESP);
2663
        else
2664
            gen_stack_update(s, (-2) << s->dflag);
2665
    }
2666
}
2667

    
2668
/* two step pop is necessary for precise exceptions */
2669
static void gen_pop_T0(DisasContext *s)
2670
{
2671
#ifdef TARGET_X86_64
2672
    if (CODE64(s)) {
2673
        gen_op_movq_A0_reg(R_ESP);
2674
        gen_op_ld_T0_A0((s->dflag ? OT_QUAD : OT_WORD) + s->mem_index);
2675
    } else
2676
#endif
2677
    {
2678
        gen_op_movl_A0_reg(R_ESP);
2679
        if (s->ss32) {
2680
            if (s->addseg)
2681
                gen_op_addl_A0_seg(s, R_SS);
2682
        } else {
2683
            gen_op_andl_A0_ffff();
2684
            gen_op_addl_A0_seg(s, R_SS);
2685
        }
2686
        gen_op_ld_T0_A0(s->dflag + 1 + s->mem_index);
2687
    }
2688
}
2689

    
2690
static void gen_pop_update(DisasContext *s)
2691
{
2692
#ifdef TARGET_X86_64
2693
    if (CODE64(s) && s->dflag) {
2694
        gen_stack_update(s, 8);
2695
    } else
2696
#endif
2697
    {
2698
        gen_stack_update(s, 2 << s->dflag);
2699
    }
2700
}
2701

    
2702
static void gen_stack_A0(DisasContext *s)
2703
{
2704
    gen_op_movl_A0_reg(R_ESP);
2705
    if (!s->ss32)
2706
        gen_op_andl_A0_ffff();
2707
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2708
    if (s->addseg)
2709
        gen_op_addl_A0_seg(s, R_SS);
2710
}
2711

    
2712
/* NOTE: wrap around in 16 bit not fully handled */
2713
static void gen_pusha(DisasContext *s)
2714
{
2715
    int i;
2716
    gen_op_movl_A0_reg(R_ESP);
2717
    gen_op_addl_A0_im(-16 <<  s->dflag);
2718
    if (!s->ss32)
2719
        gen_op_andl_A0_ffff();
2720
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2721
    if (s->addseg)
2722
        gen_op_addl_A0_seg(s, R_SS);
2723
    for(i = 0;i < 8; i++) {
2724
        gen_op_mov_TN_reg(OT_LONG, 0, 7 - i);
2725
        gen_op_st_T0_A0(OT_WORD + s->dflag + s->mem_index);
2726
        gen_op_addl_A0_im(2 <<  s->dflag);
2727
    }
2728
    gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2729
}
2730

    
2731
/* NOTE: wrap around in 16 bit not fully handled */
2732
static void gen_popa(DisasContext *s)
2733
{
2734
    int i;
2735
    gen_op_movl_A0_reg(R_ESP);
2736
    if (!s->ss32)
2737
        gen_op_andl_A0_ffff();
2738
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2739
    tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 16 <<  s->dflag);
2740
    if (s->addseg)
2741
        gen_op_addl_A0_seg(s, R_SS);
2742
    for(i = 0;i < 8; i++) {
2743
        /* ESP is not reloaded */
2744
        if (i != 3) {
2745
            gen_op_ld_T0_A0(OT_WORD + s->dflag + s->mem_index);
2746
            gen_op_mov_reg_T0(OT_WORD + s->dflag, 7 - i);
2747
        }
2748
        gen_op_addl_A0_im(2 <<  s->dflag);
2749
    }
2750
    gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2751
}
2752

    
2753
static void gen_enter(DisasContext *s, int esp_addend, int level)
2754
{
2755
    int ot, opsize;
2756

    
2757
    level &= 0x1f;
2758
#ifdef TARGET_X86_64
2759
    if (CODE64(s)) {
2760
        ot = s->dflag ? OT_QUAD : OT_WORD;
2761
        opsize = 1 << ot;
2762

    
2763
        gen_op_movl_A0_reg(R_ESP);
2764
        gen_op_addq_A0_im(-opsize);
2765
        tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2766

    
2767
        /* push bp */
2768
        gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
2769
        gen_op_st_T0_A0(ot + s->mem_index);
2770
        if (level) {
2771
            /* XXX: must save state */
2772
            gen_helper_enter64_level(cpu_env, tcg_const_i32(level),
2773
                                     tcg_const_i32((ot == OT_QUAD)),
2774
                                     cpu_T[1]);
2775
        }
2776
        gen_op_mov_reg_T1(ot, R_EBP);
2777
        tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2778
        gen_op_mov_reg_T1(OT_QUAD, R_ESP);
2779
    } else
2780
#endif
2781
    {
2782
        ot = s->dflag + OT_WORD;
2783
        opsize = 2 << s->dflag;
2784

    
2785
        gen_op_movl_A0_reg(R_ESP);
2786
        gen_op_addl_A0_im(-opsize);
2787
        if (!s->ss32)
2788
            gen_op_andl_A0_ffff();
2789
        tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2790
        if (s->addseg)
2791
            gen_op_addl_A0_seg(s, R_SS);
2792
        /* push bp */
2793
        gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
2794
        gen_op_st_T0_A0(ot + s->mem_index);
2795
        if (level) {
2796
            /* XXX: must save state */
2797
            gen_helper_enter_level(cpu_env, tcg_const_i32(level),
2798
                                   tcg_const_i32(s->dflag),
2799
                                   cpu_T[1]);
2800
        }
2801
        gen_op_mov_reg_T1(ot, R_EBP);
2802
        tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2803
        gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2804
    }
2805
}
2806

    
2807
static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2808
{
2809
    gen_update_cc_op(s);
2810
    gen_jmp_im(cur_eip);
2811
    gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
2812
    s->is_jmp = DISAS_TB_JUMP;
2813
}
2814

    
2815
/* an interrupt is different from an exception because of the
2816
   privilege checks */
2817
static void gen_interrupt(DisasContext *s, int intno,
2818
                          target_ulong cur_eip, target_ulong next_eip)
2819
{
2820
    gen_update_cc_op(s);
2821
    gen_jmp_im(cur_eip);
2822
    gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
2823
                               tcg_const_i32(next_eip - cur_eip));
2824
    s->is_jmp = DISAS_TB_JUMP;
2825
}
2826

    
2827
static void gen_debug(DisasContext *s, target_ulong cur_eip)
2828
{
2829
    gen_update_cc_op(s);
2830
    gen_jmp_im(cur_eip);
2831
    gen_helper_debug(cpu_env);
2832
    s->is_jmp = DISAS_TB_JUMP;
2833
}
2834

    
2835
/* generate a generic end of block. Trace exception is also generated
2836
   if needed */
2837
static void gen_eob(DisasContext *s)
2838
{
2839
    gen_update_cc_op(s);
2840
    if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
2841
        gen_helper_reset_inhibit_irq(cpu_env);
2842
    }
2843
    if (s->tb->flags & HF_RF_MASK) {
2844
        gen_helper_reset_rf(cpu_env);
2845
    }
2846
    if (s->singlestep_enabled) {
2847
        gen_helper_debug(cpu_env);
2848
    } else if (s->tf) {
2849
        gen_helper_single_step(cpu_env);
2850
    } else {
2851
        tcg_gen_exit_tb(0);
2852
    }
2853
    s->is_jmp = DISAS_TB_JUMP;
2854
}
2855

    
2856
/* generate a jump to eip. No segment change must happen before as a
2857
   direct call to the next block may occur */
2858
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2859
{
2860
    gen_update_cc_op(s);
2861
    set_cc_op(s, CC_OP_DYNAMIC);
2862
    if (s->jmp_opt) {
2863
        gen_goto_tb(s, tb_num, eip);
2864
        s->is_jmp = DISAS_TB_JUMP;
2865
    } else {
2866
        gen_jmp_im(eip);
2867
        gen_eob(s);
2868
    }
2869
}
2870

    
2871
static void gen_jmp(DisasContext *s, target_ulong eip)
2872
{
2873
    gen_jmp_tb(s, eip, 0);
2874
}
2875

    
2876
static inline void gen_ldq_env_A0(int idx, int offset)
2877
{
2878
    int mem_index = (idx >> 2) - 1;
2879
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2880
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
2881
}
2882

    
2883
static inline void gen_stq_env_A0(int idx, int offset)
2884
{
2885
    int mem_index = (idx >> 2) - 1;
2886
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
2887
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2888
}
2889

    
2890
static inline void gen_ldo_env_A0(int idx, int offset)
2891
{
2892
    int mem_index = (idx >> 2) - 1;
2893
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2894
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2895
    tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2896
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2897
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2898
}
2899

    
2900
static inline void gen_sto_env_A0(int idx, int offset)
2901
{
2902
    int mem_index = (idx >> 2) - 1;
2903
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2904
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2905
    tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2906
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2907
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2908
}
2909

    
2910
static inline void gen_op_movo(int d_offset, int s_offset)
2911
{
2912
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2913
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2914
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + 8);
2915
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + 8);
2916
}
2917

    
2918
static inline void gen_op_movq(int d_offset, int s_offset)
2919
{
2920
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2921
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2922
}
2923

    
2924
static inline void gen_op_movl(int d_offset, int s_offset)
2925
{
2926
    tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
2927
    tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
2928
}
2929

    
2930
static inline void gen_op_movq_env_0(int d_offset)
2931
{
2932
    tcg_gen_movi_i64(cpu_tmp1_i64, 0);
2933
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2934
}
2935

    
2936
typedef void (*SSEFunc_i_ep)(TCGv_i32 val, TCGv_ptr env, TCGv_ptr reg);
2937
typedef void (*SSEFunc_l_ep)(TCGv_i64 val, TCGv_ptr env, TCGv_ptr reg);
2938
typedef void (*SSEFunc_0_epi)(TCGv_ptr env, TCGv_ptr reg, TCGv_i32 val);
2939
typedef void (*SSEFunc_0_epl)(TCGv_ptr env, TCGv_ptr reg, TCGv_i64 val);
2940
typedef void (*SSEFunc_0_epp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b);
2941
typedef void (*SSEFunc_0_eppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2942
                               TCGv_i32 val);
2943
typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val);
2944
typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2945
                               TCGv val);
2946

    
2947
#define SSE_SPECIAL ((void *)1)
2948
#define SSE_DUMMY ((void *)2)
2949

    
2950
#define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2951
#define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2952
                     gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2953

    
2954
static const SSEFunc_0_epp sse_op_table1[256][4] = {
2955
    /* 3DNow! extensions */
2956
    [0x0e] = { SSE_DUMMY }, /* femms */
2957
    [0x0f] = { SSE_DUMMY }, /* pf... */
2958
    /* pure SSE operations */
2959
    [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2960
    [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2961
    [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2962
    [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
2963
    [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
2964
    [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
2965
    [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */
2966
    [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */
2967

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

    
2994
    [0xc2] = SSE_FOP(cmpeq),
2995
    [0xc6] = { (SSEFunc_0_epp)gen_helper_shufps,
2996
               (SSEFunc_0_epp)gen_helper_shufpd }, /* XXX: casts */
2997

    
2998
    /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX.  */
2999
    [0x38] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
3000
    [0x3a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
3001

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

    
3088
static const SSEFunc_0_epp sse_op_table2[3 * 8][2] = {
3089
    [0 + 2] = MMX_OP2(psrlw),
3090
    [0 + 4] = MMX_OP2(psraw),
3091
    [0 + 6] = MMX_OP2(psllw),
3092
    [8 + 2] = MMX_OP2(psrld),
3093
    [8 + 4] = MMX_OP2(psrad),
3094
    [8 + 6] = MMX_OP2(pslld),
3095
    [16 + 2] = MMX_OP2(psrlq),
3096
    [16 + 3] = { NULL, gen_helper_psrldq_xmm },
3097
    [16 + 6] = MMX_OP2(psllq),
3098
    [16 + 7] = { NULL, gen_helper_pslldq_xmm },
3099
};
3100

    
3101
static const SSEFunc_0_epi sse_op_table3ai[] = {
3102
    gen_helper_cvtsi2ss,
3103
    gen_helper_cvtsi2sd
3104
};
3105

    
3106
#ifdef TARGET_X86_64
3107
static const SSEFunc_0_epl sse_op_table3aq[] = {
3108
    gen_helper_cvtsq2ss,
3109
    gen_helper_cvtsq2sd
3110
};
3111
#endif
3112

    
3113
static const SSEFunc_i_ep sse_op_table3bi[] = {
3114
    gen_helper_cvttss2si,
3115
    gen_helper_cvtss2si,
3116
    gen_helper_cvttsd2si,
3117
    gen_helper_cvtsd2si
3118
};
3119

    
3120
#ifdef TARGET_X86_64
3121
static const SSEFunc_l_ep sse_op_table3bq[] = {
3122
    gen_helper_cvttss2sq,
3123
    gen_helper_cvtss2sq,
3124
    gen_helper_cvttsd2sq,
3125
    gen_helper_cvtsd2sq
3126
};
3127
#endif
3128

    
3129
static const SSEFunc_0_epp sse_op_table4[8][4] = {
3130
    SSE_FOP(cmpeq),
3131
    SSE_FOP(cmplt),
3132
    SSE_FOP(cmple),
3133
    SSE_FOP(cmpunord),
3134
    SSE_FOP(cmpneq),
3135
    SSE_FOP(cmpnlt),
3136
    SSE_FOP(cmpnle),
3137
    SSE_FOP(cmpord),
3138
};
3139

    
3140
static const SSEFunc_0_epp sse_op_table5[256] = {
3141
    [0x0c] = gen_helper_pi2fw,
3142
    [0x0d] = gen_helper_pi2fd,
3143
    [0x1c] = gen_helper_pf2iw,
3144
    [0x1d] = gen_helper_pf2id,
3145
    [0x8a] = gen_helper_pfnacc,
3146
    [0x8e] = gen_helper_pfpnacc,
3147
    [0x90] = gen_helper_pfcmpge,
3148
    [0x94] = gen_helper_pfmin,
3149
    [0x96] = gen_helper_pfrcp,
3150
    [0x97] = gen_helper_pfrsqrt,
3151
    [0x9a] = gen_helper_pfsub,
3152
    [0x9e] = gen_helper_pfadd,
3153
    [0xa0] = gen_helper_pfcmpgt,
3154
    [0xa4] = gen_helper_pfmax,
3155
    [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
3156
    [0xa7] = gen_helper_movq, /* pfrsqit1 */
3157
    [0xaa] = gen_helper_pfsubr,
3158
    [0xae] = gen_helper_pfacc,
3159
    [0xb0] = gen_helper_pfcmpeq,
3160
    [0xb4] = gen_helper_pfmul,
3161
    [0xb6] = gen_helper_movq, /* pfrcpit2 */
3162
    [0xb7] = gen_helper_pmulhrw_mmx,
3163
    [0xbb] = gen_helper_pswapd,
3164
    [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
3165
};
3166

    
3167
struct SSEOpHelper_epp {
3168
    SSEFunc_0_epp op[2];
3169
    uint32_t ext_mask;
3170
};
3171

    
3172
struct SSEOpHelper_eppi {
3173
    SSEFunc_0_eppi op[2];
3174
    uint32_t ext_mask;
3175
};
3176

    
3177
#define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
3178
#define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
3179
#define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
3180
#define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
3181

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

    
3231
static const struct SSEOpHelper_eppi sse_op_table7[256] = {
3232
    [0x08] = SSE41_OP(roundps),
3233
    [0x09] = SSE41_OP(roundpd),
3234
    [0x0a] = SSE41_OP(roundss),
3235
    [0x0b] = SSE41_OP(roundsd),
3236
    [0x0c] = SSE41_OP(blendps),
3237
    [0x0d] = SSE41_OP(blendpd),
3238
    [0x0e] = SSE41_OP(pblendw),
3239
    [0x0f] = SSSE3_OP(palignr),
3240
    [0x14] = SSE41_SPECIAL, /* pextrb */
3241
    [0x15] = SSE41_SPECIAL, /* pextrw */
3242
    [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */
3243
    [0x17] = SSE41_SPECIAL, /* extractps */
3244
    [0x20] = SSE41_SPECIAL, /* pinsrb */
3245
    [0x21] = SSE41_SPECIAL, /* insertps */
3246
    [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */
3247
    [0x40] = SSE41_OP(dpps),
3248
    [0x41] = SSE41_OP(dppd),
3249
    [0x42] = SSE41_OP(mpsadbw),
3250
    [0x60] = SSE42_OP(pcmpestrm),
3251
    [0x61] = SSE42_OP(pcmpestri),
3252
    [0x62] = SSE42_OP(pcmpistrm),
3253
    [0x63] = SSE42_OP(pcmpistri),
3254
};
3255

    
3256
static void gen_sse(CPUX86State *env, DisasContext *s, int b,
3257
                    target_ulong pc_start, int rex_r)
3258
{
3259
    int b1, op1_offset, op2_offset, is_xmm, val, ot;
3260
    int modrm, mod, rm, reg, reg_addr, offset_addr;
3261
    SSEFunc_0_epp sse_fn_epp;
3262
    SSEFunc_0_eppi sse_fn_eppi;
3263
    SSEFunc_0_ppi sse_fn_ppi;
3264
    SSEFunc_0_eppt sse_fn_eppt;
3265

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

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

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

    
3882
        case 0x138:
3883
        case 0x038:
3884
            b = modrm;
3885
            if ((b & 0xf0) == 0xf0) {
3886
                goto do_0f_38_fx;
3887
            }
3888
            modrm = cpu_ldub_code(env, s->pc++);
3889
            rm = modrm & 7;
3890
            reg = ((modrm >> 3) & 7) | rex_r;
3891
            mod = (modrm >> 6) & 3;
3892
            if (b1 >= 2) {
3893
                goto illegal_op;
3894
            }
3895

    
3896
            sse_fn_epp = sse_op_table6[b].op[b1];
3897
            if (!sse_fn_epp) {
3898
                goto illegal_op;
3899
            }
3900
            if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
3901
                goto illegal_op;
3902

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

    
3952
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3953
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3954
            sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3955

    
3956
            if (b == 0x17) {
3957
                set_cc_op(s, CC_OP_EFLAGS);
3958
            }
3959
            break;
3960

    
3961
        case 0x238:
3962
        case 0x338:
3963
        do_0f_38_fx:
3964
            /* Various integer extensions at 0f 38 f[0-f].  */
3965
            b = modrm | (b1 << 8);
3966
            modrm = cpu_ldub_code(env, s->pc++);
3967
            reg = ((modrm >> 3) & 7) | rex_r;
3968

    
3969
            switch (b) {
3970
            case 0x3f0: /* crc32 Gd,Eb */
3971
            case 0x3f1: /* crc32 Gd,Ey */
3972
            do_crc32:
3973
                if (!(s->cpuid_ext_features & CPUID_EXT_SSE42)) {
3974
                    goto illegal_op;
3975
                }
3976
                if ((b & 0xff) == 0xf0) {
3977
                    ot = OT_BYTE;
3978
                } else if (s->dflag != 2) {
3979
                    ot = (s->prefix & PREFIX_DATA ? OT_WORD : OT_LONG);
3980
                } else {
3981
                    ot = OT_QUAD;
3982
                }
3983

    
3984
                gen_op_mov_TN_reg(OT_LONG, 0, reg);
3985
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3986
                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3987
                gen_helper_crc32(cpu_T[0], cpu_tmp2_i32,
3988
                                 cpu_T[0], tcg_const_i32(8 << ot));
3989

    
3990
                ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3991
                gen_op_mov_reg_T0(ot, reg);
3992
                break;
3993

    
3994
            case 0x1f0: /* crc32 or movbe */
3995
            case 0x1f1:
3996
                /* For these insns, the f3 prefix is supposed to have priority
3997
                   over the 66 prefix, but that's not what we implement above
3998
                   setting b1.  */
3999
                if (s->prefix & PREFIX_REPNZ) {
4000
                    goto do_crc32;
4001
                }
4002
                /* FALLTHRU */
4003
            case 0x0f0: /* movbe Gy,My */
4004
            case 0x0f1: /* movbe My,Gy */
4005
                if (!(s->cpuid_ext_features & CPUID_EXT_MOVBE)) {
4006
                    goto illegal_op;
4007
                }
4008
                if (s->dflag != 2) {
4009
                    ot = (s->prefix & PREFIX_DATA ? OT_WORD : OT_LONG);
4010
                } else {
4011
                    ot = OT_QUAD;
4012
                }
4013

    
4014
                /* Load the data incoming to the bswap.  Note that the TCG
4015
                   implementation of bswap requires the input be zero
4016
                   extended.  In the case of the loads, we simply know that
4017
                   gen_op_ld_v via gen_ldst_modrm does that already.  */
4018
                if ((b & 1) == 0) {
4019
                    gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4020
                } else {
4021
                    switch (ot) {
4022
                    case OT_WORD:
4023
                        tcg_gen_ext16u_tl(cpu_T[0], cpu_regs[reg]);
4024
                        break;
4025
                    default:
4026
                        tcg_gen_ext32u_tl(cpu_T[0], cpu_regs[reg]);
4027
                        break;
4028
                    case OT_QUAD:
4029
                        tcg_gen_mov_tl(cpu_T[0], cpu_regs[reg]);
4030
                        break;
4031
                    }
4032
                }
4033

    
4034
                switch (ot) {
4035
                case OT_WORD:
4036
                    tcg_gen_bswap16_tl(cpu_T[0], cpu_T[0]);
4037
                    break;
4038
                default:
4039
                    tcg_gen_bswap32_tl(cpu_T[0], cpu_T[0]);
4040
                    break;
4041
#ifdef TARGET_X86_64
4042
                case OT_QUAD:
4043
                    tcg_gen_bswap64_tl(cpu_T[0], cpu_T[0]);
4044
                    break;
4045
#endif
4046
                }
4047

    
4048
                if ((b & 1) == 0) {
4049
                    gen_op_mov_reg_T0(ot, reg);
4050
                } else {
4051
                    gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
4052
                }
4053
                break;
4054

    
4055
            case 0x0f2: /* andn Gy, By, Ey */
4056
                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
4057
                    || !(s->prefix & PREFIX_VEX)
4058
                    || s->vex_l != 0) {
4059
                    goto illegal_op;
4060
                }
4061
                ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
4062
                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4063
                tcg_gen_andc_tl(cpu_T[0], cpu_regs[s->vex_v], cpu_T[0]);
4064
                gen_op_mov_reg_T0(ot, reg);
4065
                gen_op_update1_cc();
4066
                set_cc_op(s, CC_OP_LOGICB + ot);
4067
                break;
4068

    
4069
            case 0x0f7: /* bextr Gy, Ey, By */
4070
                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
4071
                    || !(s->prefix & PREFIX_VEX)
4072
                    || s->vex_l != 0) {
4073
                    goto illegal_op;
4074
                }
4075
                ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
4076
                {
4077
                    TCGv bound, zero;
4078

    
4079
                    gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4080
                    /* Extract START, and shift the operand.
4081
                       Shifts larger than operand size get zeros.  */
4082
                    tcg_gen_ext8u_tl(cpu_A0, cpu_regs[s->vex_v]);
4083
                    tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_A0);
4084

    
4085
                    bound = tcg_const_tl(ot == OT_QUAD ? 63 : 31);
4086
                    zero = tcg_const_tl(0);
4087
                    tcg_gen_movcond_tl(TCG_COND_LEU, cpu_T[0], cpu_A0, bound,
4088
                                       cpu_T[0], zero);
4089
                    tcg_temp_free(zero);
4090

    
4091
                    /* Extract the LEN into a mask.  Lengths larger than
4092
                       operand size get all ones.  */
4093
                    tcg_gen_shri_tl(cpu_A0, cpu_regs[s->vex_v], 8);
4094
                    tcg_gen_ext8u_tl(cpu_A0, cpu_A0);
4095
                    tcg_gen_movcond_tl(TCG_COND_LEU, cpu_A0, cpu_A0, bound,
4096
                                       cpu_A0, bound);
4097
                    tcg_temp_free(bound);
4098
                    tcg_gen_movi_tl(cpu_T[1], 1);
4099
                    tcg_gen_shl_tl(cpu_T[1], cpu_T[1], cpu_A0);
4100
                    tcg_gen_subi_tl(cpu_T[1], cpu_T[1], 1);
4101
                    tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4102

    
4103
                    gen_op_mov_reg_T0(ot, reg);
4104
                    gen_op_update1_cc();
4105
                    set_cc_op(s, CC_OP_LOGICB + ot);
4106
                }
4107
                break;
4108

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

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

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

    
4193
            case 0x2f5: /* pext Gy, By, Ey */
4194
                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4195
                    || !(s->prefix & PREFIX_VEX)
4196
                    || s->vex_l != 0) {
4197
                    goto illegal_op;
4198
                }
4199
                ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
4200
                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4201
                /* Note that by zero-extending the mask operand, we
4202
                   automatically handle zero-extending the result.  */
4203
                if (s->dflag == 2) {
4204
                    tcg_gen_mov_tl(cpu_T[1], cpu_regs[s->vex_v]);
4205
                } else {
4206
                    tcg_gen_ext32u_tl(cpu_T[1], cpu_regs[s->vex_v]);
4207
                }
4208
                gen_helper_pext(cpu_regs[reg], cpu_T[0], cpu_T[1]);
4209
                break;
4210

    
4211
            case 0x1f6: /* adcx Gy, Ey */
4212
            case 0x2f6: /* adox Gy, Ey */
4213
                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_ADX)) {
4214
                    goto illegal_op;
4215
                } else {
4216
                    TCGv carry_in, carry_out;
4217
                    int end_op;
4218

    
4219
                    ot = (s->dflag == 2 ? OT_QUAD : OT_LONG);
4220
                    gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4221

    
4222
                    /* Re-use the carry-out from a previous round.  */
4223
                    TCGV_UNUSED(carry_in);
4224
                    carry_out = (b == 0x1f6 ? cpu_cc_dst : cpu_cc_src2);
4225
                    switch (s->cc_op) {
4226
                    case CC_OP_ADCX:
4227
                        if (b == 0x1f6) {
4228
                            carry_in = cpu_cc_dst;
4229
                            end_op = CC_OP_ADCX;
4230
                        } else {
4231
                            end_op = CC_OP_ADCOX;
4232
                        }
4233
                        break;
4234
                    case CC_OP_ADOX:
4235
                        if (b == 0x1f6) {
4236
                            end_op = CC_OP_ADCOX;
4237
                        } else {
4238
                            carry_in = cpu_cc_src2;
4239
                            end_op = CC_OP_ADOX;
4240
                        }
4241
                        break;
4242
                    case CC_OP_ADCOX:
4243
                        end_op = CC_OP_ADCOX;
4244
                        carry_in = carry_out;
4245
                        break;
4246
                    default:
4247
                        end_op = (b == 0x1f6 ? CC_OP_ADCX : CC_OP_ADCOX);
4248
                        break;
4249
                    }
4250
                    /* If we can't reuse carry-out, get it out of EFLAGS.  */
4251
                    if (TCGV_IS_UNUSED(carry_in)) {
4252
                        if (s->cc_op != CC_OP_ADCX && s->cc_op != CC_OP_ADOX) {
4253
                            gen_compute_eflags(s);
4254
                        }
4255
                        carry_in = cpu_tmp0;
4256
                        tcg_gen_shri_tl(carry_in, cpu_cc_src,
4257
                                        ctz32(b == 0x1f6 ? CC_C : CC_O));
4258
                        tcg_gen_andi_tl(carry_in, carry_in, 1);
4259
                    }
4260

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

    
4292
            case 0x1f7: /* shlx Gy, Ey, By */
4293
            case 0x2f7: /* sarx Gy, Ey, By */
4294
            case 0x3f7: /* shrx Gy, Ey, By */
4295
                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4296
                    || !(s->prefix & PREFIX_VEX)
4297
                    || s->vex_l != 0) {
4298
                    goto illegal_op;
4299
                }
4300
                ot = (s->dflag == 2 ? OT_QUAD : OT_LONG);
4301
                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4302
                if (ot == OT_QUAD) {
4303
                    tcg_gen_andi_tl(cpu_T[1], cpu_regs[s->vex_v], 63);
4304
                } else {
4305
                    tcg_gen_andi_tl(cpu_T[1], cpu_regs[s->vex_v], 31);
4306
                }
4307
                if (b == 0x1f7) {
4308
                    tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4309
                } else if (b == 0x2f7) {
4310
                    if (ot != OT_QUAD) {
4311
                        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4312
                    }
4313
                    tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4314
                } else {
4315
                    if (ot != OT_QUAD) {
4316
                        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
4317
                    }
4318
                    tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4319
                }
4320
                gen_op_mov_reg_T0(ot, reg);
4321
                break;
4322

    
4323
            case 0x0f3:
4324
            case 0x1f3:
4325
            case 0x2f3:
4326
            case 0x3f3: /* Group 17 */
4327
                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
4328
                    || !(s->prefix & PREFIX_VEX)
4329
                    || s->vex_l != 0) {
4330
                    goto illegal_op;
4331
                }
4332
                ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
4333
                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4334

    
4335
                switch (reg & 7) {
4336
                case 1: /* blsr By,Ey */
4337
                    tcg_gen_neg_tl(cpu_T[1], cpu_T[0]);
4338
                    tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4339
                    gen_op_mov_reg_T0(ot, s->vex_v);
4340
                    gen_op_update2_cc();
4341
                    set_cc_op(s, CC_OP_BMILGB + ot);
4342
                    break;
4343

    
4344
                case 2: /* blsmsk By,Ey */
4345
                    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4346
                    tcg_gen_subi_tl(cpu_T[0], cpu_T[0], 1);
4347
                    tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_cc_src);
4348
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4349
                    set_cc_op(s, CC_OP_BMILGB + ot);
4350
                    break;
4351

    
4352
                case 3: /* blsi By, Ey */
4353
                    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4354
                    tcg_gen_subi_tl(cpu_T[0], cpu_T[0], 1);
4355
                    tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_cc_src);
4356
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4357
                    set_cc_op(s, CC_OP_BMILGB + ot);
4358
                    break;
4359

    
4360
                default:
4361
                    goto illegal_op;
4362
                }
4363
                break;
4364

    
4365
            default:
4366
                goto illegal_op;
4367
            }
4368
            break;
4369

    
4370
        case 0x03a:
4371
        case 0x13a:
4372
            b = modrm;
4373
            modrm = cpu_ldub_code(env, s->pc++);
4374
            rm = modrm & 7;
4375
            reg = ((modrm >> 3) & 7) | rex_r;
4376
            mod = (modrm >> 6) & 3;
4377
            if (b1 >= 2) {
4378
                goto illegal_op;
4379
            }
4380

    
4381
            sse_fn_eppi = sse_op_table7[b].op[b1];
4382
            if (!sse_fn_eppi) {
4383
                goto illegal_op;
4384
            }
4385
            if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
4386
                goto illegal_op;
4387

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

    
4518
            if (b1) {
4519
                op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4520
                if (mod == 3) {
4521
                    op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
4522
                } else {
4523
                    op2_offset = offsetof(CPUX86State,xmm_t0);
4524
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4525
                    gen_ldo_env_A0(s->mem_index, op2_offset);
4526
                }
4527
            } else {
4528
                op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4529
                if (mod == 3) {
4530
                    op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4531
                } else {
4532
                    op2_offset = offsetof(CPUX86State,mmx_t0);
4533
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4534
                    gen_ldq_env_A0(s->mem_index, op2_offset);
4535
                }
4536
            }
4537
            val = cpu_ldub_code(env, s->pc++);
4538

    
4539
            if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
4540
                set_cc_op(s, CC_OP_EFLAGS);
4541

    
4542
                if (s->dflag == 2)
4543
                    /* The helper must use entire 64-bit gp registers */
4544
                    val |= 1 << 8;
4545
            }
4546

    
4547
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4548
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4549
            sse_fn_eppi(cpu_env, cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4550
            break;
4551

    
4552
        case 0x33a:
4553
            /* Various integer extensions at 0f 3a f[0-f].  */
4554
            b = modrm | (b1 << 8);
4555
            modrm = cpu_ldub_code(env, s->pc++);
4556
            reg = ((modrm >> 3) & 7) | rex_r;
4557

    
4558
            switch (b) {
4559
            case 0x3f0: /* rorx Gy,Ey, Ib */
4560
                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4561
                    || !(s->prefix & PREFIX_VEX)
4562
                    || s->vex_l != 0) {
4563
                    goto illegal_op;
4564
                }
4565
                ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
4566
                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4567
                b = cpu_ldub_code(env, s->pc++);
4568
                if (ot == OT_QUAD) {
4569
                    tcg_gen_rotri_tl(cpu_T[0], cpu_T[0], b & 63);
4570
                } else {
4571
                    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4572
                    tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, b & 31);
4573
                    tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
4574
                }
4575
                gen_op_mov_reg_T0(ot, reg);
4576
                break;
4577

    
4578
            default:
4579
                goto illegal_op;
4580
            }
4581
            break;
4582

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

    
4660
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4661
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4662
            sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4663
            break;
4664
        case 0xf7:
4665
            /* maskmov : we must prepare A0 */
4666
            if (mod != 3)
4667
                goto illegal_op;
4668
#ifdef TARGET_X86_64
4669
            if (s->aflag == 2) {
4670
                gen_op_movq_A0_reg(R_EDI);
4671
            } else
4672
#endif
4673
            {
4674
                gen_op_movl_A0_reg(R_EDI);
4675
                if (s->aflag == 0)
4676
                    gen_op_andl_A0_ffff();
4677
            }
4678
            gen_add_A0_ds_seg(s);
4679

    
4680
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4681
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4682
            /* XXX: introduce a new table? */
4683
            sse_fn_eppt = (SSEFunc_0_eppt)sse_fn_epp;
4684
            sse_fn_eppt(cpu_env, cpu_ptr0, cpu_ptr1, cpu_A0);
4685
            break;
4686
        default:
4687
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4688
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4689
            sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4690
            break;
4691
        }
4692
        if (b == 0x2e || b == 0x2f) {
4693
            set_cc_op(s, CC_OP_EFLAGS);
4694
        }
4695
    }
4696
}
4697

    
4698
/* convert one instruction. s->is_jmp is set if the translation must
4699
   be stopped. Return the next pc value */
4700
static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
4701
                               target_ulong pc_start)
4702
{
4703
    int b, prefixes, aflag, dflag;
4704
    int shift, ot;
4705
    int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
4706
    target_ulong next_eip, tval;
4707
    int rex_w, rex_r;
4708

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

    
4788
            if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
4789
                /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4790
                   otherwise the instruction is LES or LDS.  */
4791
                break;
4792
            }
4793
            s->pc++;
4794

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

    
4837
    /* Post-process prefixes.  */
4838
    if (prefixes & PREFIX_DATA) {
4839
        dflag ^= 1;
4840
    }
4841
    if (prefixes & PREFIX_ADR) {
4842
        aflag ^= 1;
4843
    }
4844
#ifdef TARGET_X86_64
4845
    if (CODE64(s)) {
4846
        if (rex_w == 1) {
4847
            /* 0x66 is ignored if rex.w is set */
4848
            dflag = 2;
4849
        }
4850
        if (!(prefixes & PREFIX_ADR)) {
4851
            aflag = 2;
4852
        }
4853
    }
4854
#endif
4855

    
4856
    s->prefix = prefixes;
4857
    s->aflag = aflag;
4858
    s->dflag = dflag;
4859

    
4860
    /* lock generation */
4861
    if (prefixes & PREFIX_LOCK)
4862
        gen_helper_lock();
4863

    
4864
    /* now check op code */
4865
 reswitch:
4866
    switch(b) {
4867
    case 0x0f:
4868
        /**************************/
4869
        /* extended op code */
4870
        b = cpu_ldub_code(env, s->pc++) | 0x100;
4871
        goto reswitch;
4872

    
4873
        /**************************/
4874
        /* arith & logic */
4875
    case 0x00 ... 0x05:
4876
    case 0x08 ... 0x0d:
4877
    case 0x10 ... 0x15:
4878
    case 0x18 ... 0x1d:
4879
    case 0x20 ... 0x25:
4880
    case 0x28 ... 0x2d:
4881
    case 0x30 ... 0x35:
4882
    case 0x38 ... 0x3d:
4883
        {
4884
            int op, f, val;
4885
            op = (b >> 3) & 7;
4886
            f = (b >> 1) & 3;
4887

    
4888
            if ((b & 1) == 0)
4889
                ot = OT_BYTE;
4890
            else
4891
                ot = dflag + OT_WORD;
4892

    
4893
            switch(f) {
4894
            case 0: /* OP Ev, Gv */
4895
                modrm = cpu_ldub_code(env, s->pc++);
4896
                reg = ((modrm >> 3) & 7) | rex_r;
4897
                mod = (modrm >> 6) & 3;
4898
                rm = (modrm & 7) | REX_B(s);
4899
                if (mod != 3) {
4900
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4901
                    opreg = OR_TMP0;
4902
                } else if (op == OP_XORL && rm == reg) {
4903
                xor_zero:
4904
                    /* xor reg, reg optimisation */
4905
                    set_cc_op(s, CC_OP_CLR);
4906
                    gen_op_movl_T0_0();
4907
                    gen_op_mov_reg_T0(ot, reg);
4908
                    break;
4909
                } else {
4910
                    opreg = rm;
4911
                }
4912
                gen_op_mov_TN_reg(ot, 1, reg);
4913
                gen_op(s, op, ot, opreg);
4914
                break;
4915
            case 1: /* OP Gv, Ev */
4916
                modrm = cpu_ldub_code(env, s->pc++);
4917
                mod = (modrm >> 6) & 3;
4918
                reg = ((modrm >> 3) & 7) | rex_r;
4919
                rm = (modrm & 7) | REX_B(s);
4920
                if (mod != 3) {
4921
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4922
                    gen_op_ld_T1_A0(ot + s->mem_index);
4923
                } else if (op == OP_XORL && rm == reg) {
4924
                    goto xor_zero;
4925
                } else {
4926
                    gen_op_mov_TN_reg(ot, 1, rm);
4927
                }
4928
                gen_op(s, op, ot, reg);
4929
                break;
4930
            case 2: /* OP A, Iv */
4931
                val = insn_get(env, s, ot);
4932
                gen_op_movl_T1_im(val);
4933
                gen_op(s, op, ot, OR_EAX);
4934
                break;
4935
            }
4936
        }
4937
        break;
4938

    
4939
    case 0x82:
4940
        if (CODE64(s))
4941
            goto illegal_op;
4942
    case 0x80: /* GRP1 */
4943
    case 0x81:
4944
    case 0x83:
4945
        {
4946
            int val;
4947

    
4948
            if ((b & 1) == 0)
4949
                ot = OT_BYTE;
4950
            else
4951
                ot = dflag + OT_WORD;
4952

    
4953
            modrm = cpu_ldub_code(env, s->pc++);
4954
            mod = (modrm >> 6) & 3;
4955
            rm = (modrm & 7) | REX_B(s);
4956
            op = (modrm >> 3) & 7;
4957

    
4958
            if (mod != 3) {
4959
                if (b == 0x83)
4960
                    s->rip_offset = 1;
4961
                else
4962
                    s->rip_offset = insn_const_size(ot);
4963
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4964
                opreg = OR_TMP0;
4965
            } else {
4966
                opreg = rm;
4967
            }
4968

    
4969
            switch(b) {
4970
            default:
4971
            case 0x80:
4972
            case 0x81:
4973
            case 0x82:
4974
                val = insn_get(env, s, ot);
4975
                break;
4976
            case 0x83:
4977
                val = (int8_t)insn_get(env, s, OT_BYTE);
4978
                break;
4979
            }
4980
            gen_op_movl_T1_im(val);
4981
            gen_op(s, op, ot, opreg);
4982
        }
4983
        break;
4984

    
4985
        /**************************/
4986
        /* inc, dec, and other misc arith */
4987
    case 0x40 ... 0x47: /* inc Gv */
4988
        ot = dflag ? OT_LONG : OT_WORD;
4989
        gen_inc(s, ot, OR_EAX + (b & 7), 1);
4990
        break;
4991
    case 0x48 ... 0x4f: /* dec Gv */
4992
        ot = dflag ? OT_LONG : OT_WORD;
4993
        gen_inc(s, ot, OR_EAX + (b & 7), -1);
4994
        break;
4995
    case 0xf6: /* GRP3 */
4996
    case 0xf7:
4997
        if ((b & 1) == 0)
4998
            ot = OT_BYTE;
4999
        else
5000
            ot = dflag + OT_WORD;
5001

    
5002
        modrm = cpu_ldub_code(env, s->pc++);
5003
        mod = (modrm >> 6) & 3;
5004
        rm = (modrm & 7) | REX_B(s);
5005
        op = (modrm >> 3) & 7;
5006
        if (mod != 3) {
5007
            if (op == 0)
5008
                s->rip_offset = insn_const_size(ot);
5009
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5010
            gen_op_ld_T0_A0(ot + s->mem_index);
5011
        } else {
5012
            gen_op_mov_TN_reg(ot, 0, rm);
5013
        }
5014

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

    
5227
    case 0xfe: /* GRP4 */
5228
    case 0xff: /* GRP5 */
5229
        if ((b & 1) == 0)
5230
            ot = OT_BYTE;
5231
        else
5232
            ot = dflag + OT_WORD;
5233

    
5234
        modrm = cpu_ldub_code(env, s->pc++);
5235
        mod = (modrm >> 6) & 3;
5236
        rm = (modrm & 7) | REX_B(s);
5237
        op = (modrm >> 3) & 7;
5238
        if (op >= 2 && b == 0xfe) {
5239
            goto illegal_op;
5240
        }
5241
        if (CODE64(s)) {
5242
            if (op == 2 || op == 4) {
5243
                /* operand size for jumps is 64 bit */
5244
                ot = OT_QUAD;
5245
            } else if (op == 3 || op == 5) {
5246
                ot = dflag ? OT_LONG + (rex_w == 1) : OT_WORD;
5247
            } else if (op == 6) {
5248
                /* default push size is 64 bit */
5249
                ot = dflag ? OT_QUAD : OT_WORD;
5250
            }
5251
        }
5252
        if (mod != 3) {
5253
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5254
            if (op >= 2 && op != 3 && op != 5)
5255
                gen_op_ld_T0_A0(ot + s->mem_index);
5256
        } else {
5257
            gen_op_mov_TN_reg(ot, 0, rm);
5258
        }
5259

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

    
5337
    case 0x84: /* test Ev, Gv */
5338
    case 0x85:
5339
        if ((b & 1) == 0)
5340
            ot = OT_BYTE;
5341
        else
5342
            ot = dflag + OT_WORD;
5343

    
5344
        modrm = cpu_ldub_code(env, s->pc++);
5345
        reg = ((modrm >> 3) & 7) | rex_r;
5346

    
5347
        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5348
        gen_op_mov_TN_reg(ot, 1, reg);
5349
        gen_op_testl_T0_T1_cc();
5350
        set_cc_op(s, CC_OP_LOGICB + ot);
5351
        break;
5352

    
5353
    case 0xa8: /* test eAX, Iv */
5354
    case 0xa9:
5355
        if ((b & 1) == 0)
5356
            ot = OT_BYTE;
5357
        else
5358
            ot = dflag + OT_WORD;
5359
        val = insn_get(env, s, ot);
5360

    
5361
        gen_op_mov_TN_reg(ot, 0, OR_EAX);
5362
        gen_op_movl_T1_im(val);
5363
        gen_op_testl_T0_T1_cc();
5364
        set_cc_op(s, CC_OP_LOGICB + ot);
5365
        break;
5366

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

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

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

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

    
5719
        /**************************/
5720
        /* mov */
5721
    case 0x88:
5722
    case 0x89: /* mov Gv, Ev */
5723
        if ((b & 1) == 0)
5724
            ot = OT_BYTE;
5725
        else
5726
            ot = dflag + OT_WORD;
5727
        modrm = cpu_ldub_code(env, s->pc++);
5728
        reg = ((modrm >> 3) & 7) | rex_r;
5729

    
5730
        /* generate a generic store */
5731
        gen_ldst_modrm(env, s, modrm, ot, reg, 1);
5732
        break;
5733
    case 0xc6:
5734
    case 0xc7: /* mov Ev, Iv */
5735
        if ((b & 1) == 0)
5736
            ot = OT_BYTE;
5737
        else
5738
            ot = dflag + OT_WORD;
5739
        modrm = cpu_ldub_code(env, s->pc++);
5740
        mod = (modrm >> 6) & 3;
5741
        if (mod != 3) {
5742
            s->rip_offset = insn_const_size(ot);
5743
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5744
        }
5745
        val = insn_get(env, s, ot);
5746
        gen_op_movl_T0_im(val);
5747
        if (mod != 3)
5748
            gen_op_st_T0_A0(ot + s->mem_index);
5749
        else
5750
            gen_op_mov_reg_T0(ot, (modrm & 7) | REX_B(s));
5751
        break;
5752
    case 0x8a:
5753
    case 0x8b: /* mov Ev, Gv */
5754
        if ((b & 1) == 0)
5755
            ot = OT_BYTE;
5756
        else
5757
            ot = OT_WORD + dflag;
5758
        modrm = cpu_ldub_code(env, s->pc++);
5759
        reg = ((modrm >> 3) & 7) | rex_r;
5760

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

    
5798
    case 0x1b6: /* movzbS Gv, Eb */
5799
    case 0x1b7: /* movzwS Gv, Eb */
5800
    case 0x1be: /* movsbS Gv, Eb */
5801
    case 0x1bf: /* movswS Gv, Eb */
5802
        {
5803
            int d_ot;
5804
            /* d_ot is the size of destination */
5805
            d_ot = dflag + OT_WORD;
5806
            /* ot is the size of source */
5807
            ot = (b & 1) + OT_BYTE;
5808
            modrm = cpu_ldub_code(env, s->pc++);
5809
            reg = ((modrm >> 3) & 7) | rex_r;
5810
            mod = (modrm >> 6) & 3;
5811
            rm = (modrm & 7) | REX_B(s);
5812

    
5813
            if (mod == 3) {
5814
                gen_op_mov_TN_reg(ot, 0, rm);
5815
                switch(ot | (b & 8)) {
5816
                case OT_BYTE:
5817
                    tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
5818
                    break;
5819
                case OT_BYTE | 8:
5820
                    tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
5821
                    break;
5822
                case OT_WORD:
5823
                    tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
5824
                    break;
5825
                default:
5826
                case OT_WORD | 8:
5827
                    tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
5828
                    break;
5829
                }
5830
                gen_op_mov_reg_T0(d_ot, reg);
5831
            } else {
5832
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5833
                if (b & 8) {
5834
                    gen_op_lds_T0_A0(ot + s->mem_index);
5835
                } else {
5836
                    gen_op_ldu_T0_A0(ot + s->mem_index);
5837
                }
5838
                gen_op_mov_reg_T0(d_ot, reg);
5839
            }
5840
        }
5841
        break;
5842

    
5843
    case 0x8d: /* lea */
5844
        ot = dflag + OT_WORD;
5845
        modrm = cpu_ldub_code(env, s->pc++);
5846
        mod = (modrm >> 6) & 3;
5847
        if (mod == 3)
5848
            goto illegal_op;
5849
        reg = ((modrm >> 3) & 7) | rex_r;
5850
        /* we must ensure that no segment is added */
5851
        s->override = -1;
5852
        val = s->addseg;
5853
        s->addseg = 0;
5854
        gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5855
        s->addseg = val;
5856
        gen_op_mov_reg_A0(ot - OT_WORD, reg);
5857
        break;
5858

    
5859
    case 0xa0: /* mov EAX, Ov */
5860
    case 0xa1:
5861
    case 0xa2: /* mov Ov, EAX */
5862
    case 0xa3:
5863
        {
5864
            target_ulong offset_addr;
5865

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

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

    
6016
        /************************/
6017
        /* shifts */
6018
    case 0xc0:
6019
    case 0xc1:
6020
        /* shift Ev,Ib */
6021
        shift = 2;
6022
    grp2:
6023
        {
6024
            if ((b & 1) == 0)
6025
                ot = OT_BYTE;
6026
            else
6027
                ot = dflag + OT_WORD;
6028

    
6029
            modrm = cpu_ldub_code(env, s->pc++);
6030
            mod = (modrm >> 6) & 3;
6031
            op = (modrm >> 3) & 7;
6032

    
6033
            if (mod != 3) {
6034
                if (shift == 2) {
6035
                    s->rip_offset = 1;
6036
                }
6037
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
6038
                opreg = OR_TMP0;
6039
            } else {
6040
                opreg = (modrm & 7) | REX_B(s);
6041
            }
6042

    
6043
            /* simpler op */
6044
            if (shift == 0) {
6045
                gen_shift(s, op, ot, opreg, OR_ECX);
6046
            } else {
6047
                if (shift == 2) {
6048
                    shift = cpu_ldub_code(env, s->pc++);
6049
                }
6050
                gen_shifti(s, op, ot, opreg, shift);
6051
            }
6052
        }
6053
        break;
6054
    case 0xd0:
6055
    case 0xd1:
6056
        /* shift Ev,1 */
6057
        shift = 1;
6058
        goto grp2;
6059
    case 0xd2:
6060
    case 0xd3:
6061
        /* shift Ev,cl */
6062
        shift = 0;
6063
        goto grp2;
6064

    
6065
    case 0x1a4: /* shld imm */
6066
        op = 0;
6067
        shift = 1;
6068
        goto do_shiftd;
6069
    case 0x1a5: /* shld cl */
6070
        op = 0;
6071
        shift = 0;
6072
        goto do_shiftd;
6073
    case 0x1ac: /* shrd imm */
6074
        op = 1;
6075
        shift = 1;
6076
        goto do_shiftd;
6077
    case 0x1ad: /* shrd cl */
6078
        op = 1;
6079
        shift = 0;
6080
    do_shiftd:
6081
        ot = dflag + OT_WORD;
6082
        modrm = cpu_ldub_code(env, s->pc++);
6083
        mod = (modrm >> 6) & 3;
6084
        rm = (modrm & 7) | REX_B(s);
6085
        reg = ((modrm >> 3) & 7) | rex_r;
6086
        if (mod != 3) {
6087
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
6088
            opreg = OR_TMP0;
6089
        } else {
6090
            opreg = rm;
6091
        }
6092
        gen_op_mov_TN_reg(ot, 1, reg);
6093

    
6094
        if (shift) {
6095
            TCGv imm = tcg_const_tl(cpu_ldub_code(env, s->pc++));
6096
            gen_shiftd_rm_T1(s, ot, opreg, op, imm);
6097
            tcg_temp_free(imm);
6098
        } else {
6099
            gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]);
6100
        }
6101
        break;
6102

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

    
6128
                    switch(op >> 4) {
6129
                    case 0:
6130
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
6131
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6132
                        gen_helper_flds_FT0(cpu_env, cpu_tmp2_i32);
6133
                        break;
6134
                    case 1:
6135
                        gen_op_ld_T0_A0(OT_LONG + 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
                    case 2:
6140
                        tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
6141
                                          (s->mem_index >> 2) - 1);
6142
                        gen_helper_fldl_FT0(cpu_env, cpu_tmp1_i64);
6143
                        break;
6144
                    case 3:
6145
                    default:
6146
                        gen_op_lds_T0_A0(OT_WORD + s->mem_index);
6147
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6148
                        gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
6149
                        break;
6150
                    }
6151

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

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

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

    
6612
    case 0xa4: /* movsS */
6613
    case 0xa5:
6614
        if ((b & 1) == 0)
6615
            ot = OT_BYTE;
6616
        else
6617
            ot = dflag + OT_WORD;
6618

    
6619
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6620
            gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6621
        } else {
6622
            gen_movs(s, ot);
6623
        }
6624
        break;
6625

    
6626
    case 0xaa: /* stosS */
6627
    case 0xab:
6628
        if ((b & 1) == 0)
6629
            ot = OT_BYTE;
6630
        else
6631
            ot = dflag + OT_WORD;
6632

    
6633
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6634
            gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6635
        } else {
6636
            gen_stos(s, ot);
6637
        }
6638
        break;
6639
    case 0xac: /* lodsS */
6640
    case 0xad:
6641
        if ((b & 1) == 0)
6642
            ot = OT_BYTE;
6643
        else
6644
            ot = dflag + OT_WORD;
6645
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6646
            gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6647
        } else {
6648
            gen_lods(s, ot);
6649
        }
6650
        break;
6651
    case 0xae: /* scasS */
6652
    case 0xaf:
6653
        if ((b & 1) == 0)
6654
            ot = OT_BYTE;
6655
        else
6656
            ot = dflag + OT_WORD;
6657
        if (prefixes & PREFIX_REPNZ) {
6658
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6659
        } else if (prefixes & PREFIX_REPZ) {
6660
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6661
        } else {
6662
            gen_scas(s, ot);
6663
        }
6664
        break;
6665

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

    
6719
        /************************/
6720
        /* port I/O */
6721

    
6722
    case 0xe4:
6723
    case 0xe5:
6724
        if ((b & 1) == 0)
6725
            ot = OT_BYTE;
6726
        else
6727
            ot = dflag ? OT_LONG : OT_WORD;
6728
        val = cpu_ldub_code(env, s->pc++);
6729
        gen_op_movl_T0_im(val);
6730
        gen_check_io(s, ot, pc_start - s->cs_base,
6731
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6732
        if (use_icount)
6733
            gen_io_start();
6734
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6735
        gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
6736
        gen_op_mov_reg_T1(ot, R_EAX);
6737
        if (use_icount) {
6738
            gen_io_end();
6739
            gen_jmp(s, s->pc - s->cs_base);
6740
        }
6741
        break;
6742
    case 0xe6:
6743
    case 0xe7:
6744
        if ((b & 1) == 0)
6745
            ot = OT_BYTE;
6746
        else
6747
            ot = dflag ? OT_LONG : OT_WORD;
6748
        val = cpu_ldub_code(env, s->pc++);
6749
        gen_op_movl_T0_im(val);
6750
        gen_check_io(s, ot, pc_start - s->cs_base,
6751
                     svm_is_rep(prefixes));
6752
        gen_op_mov_TN_reg(ot, 1, R_EAX);
6753

    
6754
        if (use_icount)
6755
            gen_io_start();
6756
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6757
        tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
6758
        gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6759
        if (use_icount) {
6760
            gen_io_end();
6761
            gen_jmp(s, s->pc - s->cs_base);
6762
        }
6763
        break;
6764
    case 0xec:
6765
    case 0xed:
6766
        if ((b & 1) == 0)
6767
            ot = OT_BYTE;
6768
        else
6769
            ot = dflag ? OT_LONG : OT_WORD;
6770
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6771
        gen_op_andl_T0_ffff();
6772
        gen_check_io(s, ot, pc_start - s->cs_base,
6773
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6774
        if (use_icount)
6775
            gen_io_start();
6776
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6777
        gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
6778
        gen_op_mov_reg_T1(ot, R_EAX);
6779
        if (use_icount) {
6780
            gen_io_end();
6781
            gen_jmp(s, s->pc - s->cs_base);
6782
        }
6783
        break;
6784
    case 0xee:
6785
    case 0xef:
6786
        if ((b & 1) == 0)
6787
            ot = OT_BYTE;
6788
        else
6789
            ot = dflag ? OT_LONG : OT_WORD;
6790
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6791
        gen_op_andl_T0_ffff();
6792
        gen_check_io(s, ot, pc_start - s->cs_base,
6793
                     svm_is_rep(prefixes));
6794
        gen_op_mov_TN_reg(ot, 1, R_EAX);
6795

    
6796
        if (use_icount)
6797
            gen_io_start();
6798
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6799
        tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
6800
        gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6801
        if (use_icount) {
6802
            gen_io_end();
6803
            gen_jmp(s, s->pc - s->cs_base);
6804
        }
6805
        break;
6806

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

    
6902
            if (CODE64(s))
6903
                goto illegal_op;
6904
            ot = dflag ? OT_LONG : OT_WORD;
6905
            offset = insn_get(env, s, ot);
6906
            selector = insn_get(env, s, OT_WORD);
6907

    
6908
            gen_op_movl_T0_im(selector);
6909
            gen_op_movl_T1_imu(offset);
6910
        }
6911
        goto do_lcall;
6912
    case 0xe9: /* jmp im */
6913
        if (dflag)
6914
            tval = (int32_t)insn_get(env, s, OT_LONG);
6915
        else
6916
            tval = (int16_t)insn_get(env, s, OT_WORD);
6917
        tval += s->pc - s->cs_base;
6918
        if (s->dflag == 0)
6919
            tval &= 0xffff;
6920
        else if(!CODE64(s))
6921
            tval &= 0xffffffff;
6922
        gen_jmp(s, tval);
6923
        break;
6924
    case 0xea: /* ljmp im */
6925
        {
6926
            unsigned int selector, offset;
6927

    
6928
            if (CODE64(s))
6929
                goto illegal_op;
6930
            ot = dflag ? OT_LONG : OT_WORD;
6931
            offset = insn_get(env, s, ot);
6932
            selector = insn_get(env, s, OT_WORD);
6933

    
6934
            gen_op_movl_T0_im(selector);
6935
            gen_op_movl_T1_imu(offset);
6936
        }
6937
        goto do_ljmp;
6938
    case 0xeb: /* jmp Jb */
6939
        tval = (int8_t)insn_get(env, s, OT_BYTE);
6940
        tval += s->pc - s->cs_base;
6941
        if (s->dflag == 0)
6942
            tval &= 0xffff;
6943
        gen_jmp(s, tval);
6944
        break;
6945
    case 0x70 ... 0x7f: /* jcc Jb */
6946
        tval = (int8_t)insn_get(env, s, OT_BYTE);
6947
        goto do_jcc;
6948
    case 0x180 ... 0x18f: /* jcc Jv */
6949
        if (dflag) {
6950
            tval = (int32_t)insn_get(env, s, OT_LONG);
6951
        } else {
6952
            tval = (int16_t)insn_get(env, s, OT_WORD);
6953
        }
6954
    do_jcc:
6955
        next_eip = s->pc - s->cs_base;
6956
        tval += next_eip;
6957
        if (s->dflag == 0)
6958
            tval &= 0xffff;
6959
        gen_jcc(s, b, tval, next_eip);
6960
        break;
6961

    
6962
    case 0x190 ... 0x19f: /* setcc Gv */
6963
        modrm = cpu_ldub_code(env, s->pc++);
6964
        gen_setcc1(s, b, cpu_T[0]);
6965
        gen_ldst_modrm(env, s, modrm, OT_BYTE, OR_TMP0, 1);
6966
        break;
6967
    case 0x140 ... 0x14f: /* cmov Gv, Ev */
6968
        ot = dflag + OT_WORD;
6969
        modrm = cpu_ldub_code(env, s->pc++);
6970
        reg = ((modrm >> 3) & 7) | rex_r;
6971
        gen_cmovcc1(env, s, ot, b, modrm, reg);
6972
        break;
6973

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

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

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

    
7415
            tval = (int8_t)insn_get(env, s, OT_BYTE);
7416
            next_eip = s->pc - s->cs_base;
7417
            tval += next_eip;
7418
            if (s->dflag == 0)
7419
                tval &= 0xffff;
7420

    
7421
            l1 = gen_new_label();
7422
            l2 = gen_new_label();
7423
            l3 = gen_new_label();
7424
            b &= 3;
7425
            switch(b) {
7426
            case 0: /* loopnz */
7427
            case 1: /* loopz */
7428
                gen_op_add_reg_im(s->aflag, R_ECX, -1);
7429
                gen_op_jz_ecx(s->aflag, l3);
7430
                gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
7431
                break;
7432
            case 2: /* loop */
7433
                gen_op_add_reg_im(s->aflag, R_ECX, -1);
7434
                gen_op_jnz_ecx(s->aflag, l1);
7435
                break;
7436
            default:
7437
            case 3: /* jcxz */
7438
                gen_op_jz_ecx(s->aflag, l1);
7439
                break;
7440
            }
7441

    
7442
            gen_set_label(l3);
7443
            gen_jmp_im(next_eip);
7444
            tcg_gen_br(l2);
7445

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

    
7896
            modrm = cpu_ldub_code(env, s->pc++);
7897
            reg = ((modrm >> 3) & 7) | rex_r;
7898
            mod = (modrm >> 6) & 3;
7899
            rm = (modrm & 7) | REX_B(s);
7900

    
7901
            if (mod == 3) {
7902
                gen_op_mov_TN_reg(OT_LONG, 0, rm);
7903
                /* sign extend */
7904
                if (d_ot == OT_QUAD)
7905
                    tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
7906
                gen_op_mov_reg_T0(d_ot, reg);
7907
            } else {
7908
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7909
                if (d_ot == OT_QUAD) {
7910
                    gen_op_lds_T0_A0(OT_LONG + s->mem_index);
7911
                } else {
7912
                    gen_op_ld_T0_A0(OT_LONG + s->mem_index);
7913
                }
7914
                gen_op_mov_reg_T0(d_ot, reg);
7915
            }
7916
        } else
7917
#endif
7918
        {
7919
            int label1;
7920
            TCGv t0, t1, t2, a0;
7921

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

    
8214
        modrm = cpu_ldub_code(env, s->pc++);
8215
        reg = ((modrm >> 3) & 7) | rex_r;
8216

    
8217
        if (s->prefix & PREFIX_DATA)
8218
            ot = OT_WORD;
8219
        else if (s->dflag != 2)
8220
            ot = OT_LONG;
8221
        else
8222
            ot = OT_QUAD;
8223

    
8224
        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
8225
        gen_helper_popcnt(cpu_T[0], cpu_env, cpu_T[0], tcg_const_i32(ot));
8226
        gen_op_mov_reg_T0(ot, reg);
8227

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

    
8258
void optimize_flags_init(void)
8259
{
8260
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8261
    cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0,
8262
                                       offsetof(CPUX86State, cc_op), "cc_op");
8263
    cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_dst),
8264
                                    "cc_dst");
8265
    cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_src),
8266
                                    "cc_src");
8267
    cpu_cc_src2 = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_src2),
8268
                                     "cc_src2");
8269

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

    
8322
    /* register helpers */
8323
#define GEN_HELPER 2
8324
#include "helper.h"
8325
}
8326

    
8327
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8328
   basic block 'tb'. If search_pc is TRUE, also generate PC
8329
   information for each intermediate instruction. */
8330
static inline void gen_intermediate_code_internal(CPUX86State *env,
8331
                                                  TranslationBlock *tb,
8332
                                                  int search_pc)
8333
{
8334
    DisasContext dc1, *dc = &dc1;
8335
    target_ulong pc_ptr;
8336
    uint16_t *gen_opc_end;
8337
    CPUBreakpoint *bp;
8338
    int j, lj;
8339
    uint64_t flags;
8340
    target_ulong pc_start;
8341
    target_ulong cs_base;
8342
    int num_insns;
8343
    int max_insns;
8344

    
8345
    /* generate intermediate code */
8346
    pc_start = tb->pc;
8347
    cs_base = tb->cs_base;
8348
    flags = tb->flags;
8349

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

    
8392
    cpu_T[0] = tcg_temp_new();
8393
    cpu_T[1] = tcg_temp_new();
8394
    cpu_A0 = tcg_temp_new();
8395

    
8396
    cpu_tmp0 = tcg_temp_new();
8397
    cpu_tmp1_i64 = tcg_temp_new_i64();
8398
    cpu_tmp2_i32 = tcg_temp_new_i32();
8399
    cpu_tmp3_i32 = tcg_temp_new_i32();
8400
    cpu_tmp4 = tcg_temp_new();
8401
    cpu_tmp5 = tcg_temp_new();
8402
    cpu_ptr0 = tcg_temp_new_ptr();
8403
    cpu_ptr1 = tcg_temp_new_ptr();
8404
    cpu_cc_srcT = tcg_temp_local_new();
8405

    
8406
    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
8407

    
8408
    dc->is_jmp = DISAS_NEXT;
8409
    pc_ptr = pc_start;
8410
    lj = -1;
8411
    num_insns = 0;
8412
    max_insns = tb->cflags & CF_COUNT_MASK;
8413
    if (max_insns == 0)
8414
        max_insns = CF_COUNT_MASK;
8415

    
8416
    gen_icount_start();
8417
    for(;;) {
8418
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
8419
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
8420
                if (bp->pc == pc_ptr &&
8421
                    !((bp->flags & BP_CPU) && (tb->flags & HF_RF_MASK))) {
8422
                    gen_debug(dc, pc_ptr - dc->cs_base);
8423
                    break;
8424
                }
8425
            }
8426
        }
8427
        if (search_pc) {
8428
            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
8429
            if (lj < j) {
8430
                lj++;
8431
                while (lj < j)
8432
                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
8433
            }
8434
            tcg_ctx.gen_opc_pc[lj] = pc_ptr;
8435
            gen_opc_cc_op[lj] = dc->cc_op;
8436
            tcg_ctx.gen_opc_instr_start[lj] = 1;
8437
            tcg_ctx.gen_opc_icount[lj] = num_insns;
8438
        }
8439
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8440
            gen_io_start();
8441

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

    
8484
#ifdef DEBUG_DISAS
8485
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8486
        int disas_flags;
8487
        qemu_log("----------------\n");
8488
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
8489
#ifdef TARGET_X86_64
8490
        if (dc->code64)
8491
            disas_flags = 2;
8492
        else
8493
#endif
8494
            disas_flags = !dc->code32;
8495
        log_target_disas(env, pc_start, pc_ptr - pc_start, disas_flags);
8496
        qemu_log("\n");
8497
    }
8498
#endif
8499

    
8500
    if (!search_pc) {
8501
        tb->size = pc_ptr - pc_start;
8502
        tb->icount = num_insns;
8503
    }
8504
}
8505

    
8506
void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
8507
{
8508
    gen_intermediate_code_internal(env, tb, 0);
8509
}
8510

    
8511
void gen_intermediate_code_pc(CPUX86State *env, TranslationBlock *tb)
8512
{
8513
    gen_intermediate_code_internal(env, tb, 1);
8514
}
8515

    
8516
void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, int pc_pos)
8517
{
8518
    int cc_op;
8519
#ifdef DEBUG_DISAS
8520
    if (qemu_loglevel_mask(CPU_LOG_TB_OP)) {
8521
        int i;
8522
        qemu_log("RESTORE:\n");
8523
        for(i = 0;i <= pc_pos; i++) {
8524
            if (tcg_ctx.gen_opc_instr_start[i]) {
8525
                qemu_log("0x%04x: " TARGET_FMT_lx "\n", i,
8526
                        tcg_ctx.gen_opc_pc[i]);
8527
            }
8528
        }
8529
        qemu_log("pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
8530
                pc_pos, tcg_ctx.gen_opc_pc[pc_pos] - tb->cs_base,
8531
                (uint32_t)tb->cs_base);
8532
    }
8533
#endif
8534
    env->eip = tcg_ctx.gen_opc_pc[pc_pos] - tb->cs_base;
8535
    cc_op = gen_opc_cc_op[pc_pos];
8536
    if (cc_op != CC_OP_DYNAMIC)
8537
        env->cc_op = cc_op;
8538
}