Statistics
| Branch: | Revision:

root / target-i386 / translate.c @ 701ed211

History | View | Annotate | Download (264.1 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
};
213

    
214
static void set_cc_op(DisasContext *s, CCOp op)
215
{
216
    int dead;
217

    
218
    if (s->cc_op == op) {
219
        return;
220
    }
221

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

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

    
243
static void gen_update_cc_op(DisasContext *s)
244
{
245
    if (s->cc_op_dirty) {
246
        tcg_gen_movi_i32(cpu_cc_op, s->cc_op);
247
        s->cc_op_dirty = false;
248
    }
249
}
250

    
251
static inline void gen_op_movl_T0_0(void)
252
{
253
    tcg_gen_movi_tl(cpu_T[0], 0);
254
}
255

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

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

    
266
static inline void gen_op_movl_T1_im(int32_t val)
267
{
268
    tcg_gen_movi_tl(cpu_T[1], val);
269
}
270

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

    
276
static inline void gen_op_movl_A0_im(uint32_t val)
277
{
278
    tcg_gen_movi_tl(cpu_A0, val);
279
}
280

    
281
#ifdef TARGET_X86_64
282
static inline void gen_op_movq_A0_im(int64_t val)
283
{
284
    tcg_gen_movi_tl(cpu_A0, val);
285
}
286
#endif
287

    
288
static inline void gen_movtl_T0_im(target_ulong val)
289
{
290
    tcg_gen_movi_tl(cpu_T[0], val);
291
}
292

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

    
298
static inline void gen_op_andl_T0_ffff(void)
299
{
300
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
301
}
302

    
303
static inline void gen_op_andl_T0_im(uint32_t val)
304
{
305
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], val);
306
}
307

    
308
static inline void gen_op_movl_T0_T1(void)
309
{
310
    tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
311
}
312

    
313
static inline void gen_op_andl_A0_ffff(void)
314
{
315
    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffff);
316
}
317

    
318
#ifdef TARGET_X86_64
319

    
320
#define NB_OP_SIZES 4
321

    
322
#else /* !TARGET_X86_64 */
323

    
324
#define NB_OP_SIZES 3
325

    
326
#endif /* !TARGET_X86_64 */
327

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

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

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

    
388
static inline void gen_op_mov_reg_T0(int ot, int reg)
389
{
390
    gen_op_mov_reg_v(ot, reg, cpu_T[0]);
391
}
392

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

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

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

    
428
static inline void gen_op_mov_TN_reg(int ot, int t_index, int reg)
429
{
430
    gen_op_mov_v_reg(ot, cpu_T[t_index], reg);
431
}
432

    
433
static inline void gen_op_movl_A0_reg(int reg)
434
{
435
    tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
436
}
437

    
438
static inline void gen_op_addl_A0_im(int32_t val)
439
{
440
    tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
441
#ifdef TARGET_X86_64
442
    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
443
#endif
444
}
445

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

    
463
static inline void gen_op_addl_T0_T1(void)
464
{
465
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
466
}
467

    
468
static inline void gen_op_jmp_T0(void)
469
{
470
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, eip));
471
}
472

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

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

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

    
528
static inline void gen_op_movl_A0_seg(int reg)
529
{
530
    tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUX86State, segs[reg].base) + REG_L_OFFSET);
531
}
532

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

    
549
#ifdef TARGET_X86_64
550
static inline void gen_op_movq_A0_seg(int reg)
551
{
552
    tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUX86State, segs[reg].base));
553
}
554

    
555
static inline void gen_op_addq_A0_seg(int reg)
556
{
557
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, segs[reg].base));
558
    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
559
}
560

    
561
static inline void gen_op_movq_A0_reg(int reg)
562
{
563
    tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
564
}
565

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

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

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

    
615
/* XXX: always use ldu or lds */
616
static inline void gen_op_ld_T0_A0(int idx)
617
{
618
    gen_op_ld_v(idx, cpu_T[0], cpu_A0);
619
}
620

    
621
static inline void gen_op_ldu_T0_A0(int idx)
622
{
623
    gen_op_ld_v(idx, cpu_T[0], cpu_A0);
624
}
625

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

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

    
654
static inline void gen_op_st_T0_A0(int idx)
655
{
656
    gen_op_st_v(idx, cpu_T[0], cpu_A0);
657
}
658

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

    
664
static inline void gen_jmp_im(target_ulong pc)
665
{
666
    tcg_gen_movi_tl(cpu_tmp0, pc);
667
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, eip));
668
}
669

    
670
static inline void gen_string_movl_A0_ESI(DisasContext *s)
671
{
672
    int override;
673

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

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

    
726
static inline void gen_op_movl_T0_Dshift(int ot) 
727
{
728
    tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, df));
729
    tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot);
730
};
731

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

    
763
static void gen_extu(int ot, TCGv reg)
764
{
765
    gen_ext_tl(reg, reg, ot, false);
766
}
767

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

    
773
static inline void gen_op_jnz_ecx(int size, int label1)
774
{
775
    tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
776
    gen_extu(size + 1, cpu_tmp0);
777
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
778
}
779

    
780
static inline void gen_op_jz_ecx(int size, int label1)
781
{
782
    tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
783
    gen_extu(size + 1, cpu_tmp0);
784
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
785
}
786

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

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

    
817
static void gen_check_io(DisasContext *s, int ot, target_ulong cur_eip,
818
                         uint32_t svm_flags)
819
{
820
    int state_saved;
821
    target_ulong next_eip;
822

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

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

    
866
static void gen_op_update1_cc(void)
867
{
868
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
869
}
870

    
871
static void gen_op_update2_cc(void)
872
{
873
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
874
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
875
}
876

    
877
static void gen_op_update3_cc(TCGv reg)
878
{
879
    tcg_gen_mov_tl(cpu_cc_src2, reg);
880
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
881
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
882
}
883

    
884
static inline void gen_op_testl_T0_T1_cc(void)
885
{
886
    tcg_gen_and_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
887
}
888

    
889
static void gen_op_update_neg_cc(void)
890
{
891
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
892
    tcg_gen_neg_tl(cpu_cc_src, cpu_T[0]);
893
    tcg_gen_movi_tl(cpu_cc_srcT, 0);
894
}
895

    
896
/* compute all eflags to cc_src */
897
static void gen_compute_eflags(DisasContext *s)
898
{
899
    TCGv zero, dst, src1, src2;
900
    int live, dead;
901

    
902
    if (s->cc_op == CC_OP_EFLAGS) {
903
        return;
904
    }
905

    
906
    TCGV_UNUSED(zero);
907
    dst = cpu_cc_dst;
908
    src1 = cpu_cc_src;
909
    src2 = cpu_cc_src2;
910

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

    
927
    gen_update_cc_op(s);
928
    gen_helper_cc_compute_all(cpu_cc_src, dst, src1, src2, cpu_cc_op);
929
    set_cc_op(s, CC_OP_EFLAGS);
930

    
931
    if (dead) {
932
        tcg_temp_free(zero);
933
    }
934
}
935

    
936
typedef struct CCPrepare {
937
    TCGCond cond;
938
    TCGv reg;
939
    TCGv reg2;
940
    target_ulong imm;
941
    target_ulong mask;
942
    bool use_reg2;
943
    bool no_setcond;
944
} CCPrepare;
945

    
946
/* compute eflags.C to reg */
947
static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
948
{
949
    TCGv t0, t1;
950
    int size, shift;
951

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

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

    
972
    case CC_OP_LOGICB ... CC_OP_LOGICQ:
973
        return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
974

    
975
    case CC_OP_INCB ... CC_OP_INCQ:
976
    case CC_OP_DECB ... CC_OP_DECQ:
977
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
978
                             .mask = -1, .no_setcond = true };
979

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

    
987
    case CC_OP_MULB ... CC_OP_MULQ:
988
        return (CCPrepare) { .cond = TCG_COND_NE,
989
                             .reg = cpu_cc_src, .mask = -1 };
990

    
991
    case CC_OP_EFLAGS:
992
    case CC_OP_SARB ... CC_OP_SARQ:
993
        /* CC_SRC & 1 */
994
        return (CCPrepare) { .cond = TCG_COND_NE,
995
                             .reg = cpu_cc_src, .mask = CC_C };
996

    
997
    default:
998
       /* The need to compute only C from CC_OP_DYNAMIC is important
999
          in efficiently implementing e.g. INC at the start of a TB.  */
1000
       gen_update_cc_op(s);
1001
       gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src,
1002
                               cpu_cc_src2, cpu_cc_op);
1003
       return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
1004
                            .mask = -1, .no_setcond = true };
1005
    }
1006
}
1007

    
1008
/* compute eflags.P to reg */
1009
static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg)
1010
{
1011
    gen_compute_eflags(s);
1012
    return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1013
                         .mask = CC_P };
1014
}
1015

    
1016
/* compute eflags.S to reg */
1017
static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg)
1018
{
1019
    switch (s->cc_op) {
1020
    case CC_OP_DYNAMIC:
1021
        gen_compute_eflags(s);
1022
        /* FALLTHRU */
1023
    case CC_OP_EFLAGS:
1024
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1025
                             .mask = CC_S };
1026
    default:
1027
        {
1028
            int size = (s->cc_op - CC_OP_ADDB) & 3;
1029
            TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true);
1030
            return (CCPrepare) { .cond = TCG_COND_LT, .reg = t0, .mask = -1 };
1031
        }
1032
    }
1033
}
1034

    
1035
/* compute eflags.O to reg */
1036
static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg)
1037
{
1038
    gen_compute_eflags(s);
1039
    return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1040
                         .mask = CC_O };
1041
}
1042

    
1043
/* compute eflags.Z to reg */
1044
static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg)
1045
{
1046
    switch (s->cc_op) {
1047
    case CC_OP_DYNAMIC:
1048
        gen_compute_eflags(s);
1049
        /* FALLTHRU */
1050
    case CC_OP_EFLAGS:
1051
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1052
                             .mask = CC_Z };
1053
    default:
1054
        {
1055
            int size = (s->cc_op - CC_OP_ADDB) & 3;
1056
            TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
1057
            return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
1058
        }
1059
    }
1060
}
1061

    
1062
/* perform a conditional store into register 'reg' according to jump opcode
1063
   value 'b'. In the fast case, T0 is guaranted not to be used. */
1064
static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
1065
{
1066
    int inv, jcc_op, size, cond;
1067
    CCPrepare cc;
1068
    TCGv t0;
1069

    
1070
    inv = b & 1;
1071
    jcc_op = (b >> 1) & 7;
1072

    
1073
    switch (s->cc_op) {
1074
    case CC_OP_SUBB ... CC_OP_SUBQ:
1075
        /* We optimize relational operators for the cmp/jcc case.  */
1076
        size = s->cc_op - CC_OP_SUBB;
1077
        switch (jcc_op) {
1078
        case JCC_BE:
1079
            tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
1080
            gen_extu(size, cpu_tmp4);
1081
            t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
1082
            cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = cpu_tmp4,
1083
                               .reg2 = t0, .mask = -1, .use_reg2 = true };
1084
            break;
1085

    
1086
        case JCC_L:
1087
            cond = TCG_COND_LT;
1088
            goto fast_jcc_l;
1089
        case JCC_LE:
1090
            cond = TCG_COND_LE;
1091
        fast_jcc_l:
1092
            tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
1093
            gen_exts(size, cpu_tmp4);
1094
            t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, true);
1095
            cc = (CCPrepare) { .cond = cond, .reg = cpu_tmp4,
1096
                               .reg2 = t0, .mask = -1, .use_reg2 = true };
1097
            break;
1098

    
1099
        default:
1100
            goto slow_jcc;
1101
        }
1102
        break;
1103

    
1104
    default:
1105
    slow_jcc:
1106
        /* This actually generates good code for JC, JZ and JS.  */
1107
        switch (jcc_op) {
1108
        case JCC_O:
1109
            cc = gen_prepare_eflags_o(s, reg);
1110
            break;
1111
        case JCC_B:
1112
            cc = gen_prepare_eflags_c(s, reg);
1113
            break;
1114
        case JCC_Z:
1115
            cc = gen_prepare_eflags_z(s, reg);
1116
            break;
1117
        case JCC_BE:
1118
            gen_compute_eflags(s);
1119
            cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1120
                               .mask = CC_Z | CC_C };
1121
            break;
1122
        case JCC_S:
1123
            cc = gen_prepare_eflags_s(s, reg);
1124
            break;
1125
        case JCC_P:
1126
            cc = gen_prepare_eflags_p(s, reg);
1127
            break;
1128
        case JCC_L:
1129
            gen_compute_eflags(s);
1130
            if (TCGV_EQUAL(reg, cpu_cc_src)) {
1131
                reg = cpu_tmp0;
1132
            }
1133
            tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
1134
            tcg_gen_xor_tl(reg, reg, cpu_cc_src);
1135
            cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
1136
                               .mask = CC_S };
1137
            break;
1138
        default:
1139
        case JCC_LE:
1140
            gen_compute_eflags(s);
1141
            if (TCGV_EQUAL(reg, cpu_cc_src)) {
1142
                reg = cpu_tmp0;
1143
            }
1144
            tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
1145
            tcg_gen_xor_tl(reg, reg, cpu_cc_src);
1146
            cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
1147
                               .mask = CC_S | CC_Z };
1148
            break;
1149
        }
1150
        break;
1151
    }
1152

    
1153
    if (inv) {
1154
        cc.cond = tcg_invert_cond(cc.cond);
1155
    }
1156
    return cc;
1157
}
1158

    
1159
static void gen_setcc1(DisasContext *s, int b, TCGv reg)
1160
{
1161
    CCPrepare cc = gen_prepare_cc(s, b, reg);
1162

    
1163
    if (cc.no_setcond) {
1164
        if (cc.cond == TCG_COND_EQ) {
1165
            tcg_gen_xori_tl(reg, cc.reg, 1);
1166
        } else {
1167
            tcg_gen_mov_tl(reg, cc.reg);
1168
        }
1169
        return;
1170
    }
1171

    
1172
    if (cc.cond == TCG_COND_NE && !cc.use_reg2 && cc.imm == 0 &&
1173
        cc.mask != 0 && (cc.mask & (cc.mask - 1)) == 0) {
1174
        tcg_gen_shri_tl(reg, cc.reg, ctztl(cc.mask));
1175
        tcg_gen_andi_tl(reg, reg, 1);
1176
        return;
1177
    }
1178
    if (cc.mask != -1) {
1179
        tcg_gen_andi_tl(reg, cc.reg, cc.mask);
1180
        cc.reg = reg;
1181
    }
1182
    if (cc.use_reg2) {
1183
        tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1184
    } else {
1185
        tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm);
1186
    }
1187
}
1188

    
1189
static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg)
1190
{
1191
    gen_setcc1(s, JCC_B << 1, reg);
1192
}
1193

    
1194
/* generate a conditional jump to label 'l1' according to jump opcode
1195
   value 'b'. In the fast case, T0 is guaranted not to be used. */
1196
static inline void gen_jcc1_noeob(DisasContext *s, int b, int l1)
1197
{
1198
    CCPrepare cc = gen_prepare_cc(s, b, cpu_T[0]);
1199

    
1200
    if (cc.mask != -1) {
1201
        tcg_gen_andi_tl(cpu_T[0], cc.reg, cc.mask);
1202
        cc.reg = cpu_T[0];
1203
    }
1204
    if (cc.use_reg2) {
1205
        tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1206
    } else {
1207
        tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1208
    }
1209
}
1210

    
1211
/* Generate a conditional jump to label 'l1' according to jump opcode
1212
   value 'b'. In the fast case, T0 is guaranted not to be used.
1213
   A translation block must end soon.  */
1214
static inline void gen_jcc1(DisasContext *s, int b, int l1)
1215
{
1216
    CCPrepare cc = gen_prepare_cc(s, b, cpu_T[0]);
1217

    
1218
    gen_update_cc_op(s);
1219
    if (cc.mask != -1) {
1220
        tcg_gen_andi_tl(cpu_T[0], cc.reg, cc.mask);
1221
        cc.reg = cpu_T[0];
1222
    }
1223
    set_cc_op(s, CC_OP_DYNAMIC);
1224
    if (cc.use_reg2) {
1225
        tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1226
    } else {
1227
        tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1228
    }
1229
}
1230

    
1231
/* XXX: does not work with gdbstub "ice" single step - not a
1232
   serious problem */
1233
static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
1234
{
1235
    int l1, l2;
1236

    
1237
    l1 = gen_new_label();
1238
    l2 = gen_new_label();
1239
    gen_op_jnz_ecx(s->aflag, l1);
1240
    gen_set_label(l2);
1241
    gen_jmp_tb(s, next_eip, 1);
1242
    gen_set_label(l1);
1243
    return l2;
1244
}
1245

    
1246
static inline void gen_stos(DisasContext *s, int ot)
1247
{
1248
    gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
1249
    gen_string_movl_A0_EDI(s);
1250
    gen_op_st_T0_A0(ot + s->mem_index);
1251
    gen_op_movl_T0_Dshift(ot);
1252
    gen_op_add_reg_T0(s->aflag, R_EDI);
1253
}
1254

    
1255
static inline void gen_lods(DisasContext *s, int ot)
1256
{
1257
    gen_string_movl_A0_ESI(s);
1258
    gen_op_ld_T0_A0(ot + s->mem_index);
1259
    gen_op_mov_reg_T0(ot, R_EAX);
1260
    gen_op_movl_T0_Dshift(ot);
1261
    gen_op_add_reg_T0(s->aflag, R_ESI);
1262
}
1263

    
1264
static inline void gen_scas(DisasContext *s, int ot)
1265
{
1266
    gen_string_movl_A0_EDI(s);
1267
    gen_op_ld_T1_A0(ot + s->mem_index);
1268
    gen_op(s, OP_CMPL, ot, R_EAX);
1269
    gen_op_movl_T0_Dshift(ot);
1270
    gen_op_add_reg_T0(s->aflag, R_EDI);
1271
}
1272

    
1273
static inline void gen_cmps(DisasContext *s, int ot)
1274
{
1275
    gen_string_movl_A0_EDI(s);
1276
    gen_op_ld_T1_A0(ot + s->mem_index);
1277
    gen_string_movl_A0_ESI(s);
1278
    gen_op(s, OP_CMPL, ot, OR_TMP0);
1279
    gen_op_movl_T0_Dshift(ot);
1280
    gen_op_add_reg_T0(s->aflag, R_ESI);
1281
    gen_op_add_reg_T0(s->aflag, R_EDI);
1282
}
1283

    
1284
static inline void gen_ins(DisasContext *s, int ot)
1285
{
1286
    if (use_icount)
1287
        gen_io_start();
1288
    gen_string_movl_A0_EDI(s);
1289
    /* Note: we must do this dummy write first to be restartable in
1290
       case of page fault. */
1291
    gen_op_movl_T0_0();
1292
    gen_op_st_T0_A0(ot + s->mem_index);
1293
    gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
1294
    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
1295
    tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1296
    gen_helper_in_func(ot, cpu_T[0], cpu_tmp2_i32);
1297
    gen_op_st_T0_A0(ot + s->mem_index);
1298
    gen_op_movl_T0_Dshift(ot);
1299
    gen_op_add_reg_T0(s->aflag, R_EDI);
1300
    if (use_icount)
1301
        gen_io_end();
1302
}
1303

    
1304
static inline void gen_outs(DisasContext *s, int ot)
1305
{
1306
    if (use_icount)
1307
        gen_io_start();
1308
    gen_string_movl_A0_ESI(s);
1309
    gen_op_ld_T0_A0(ot + s->mem_index);
1310

    
1311
    gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
1312
    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
1313
    tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1314
    tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]);
1315
    gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
1316

    
1317
    gen_op_movl_T0_Dshift(ot);
1318
    gen_op_add_reg_T0(s->aflag, R_ESI);
1319
    if (use_icount)
1320
        gen_io_end();
1321
}
1322

    
1323
/* same method as Valgrind : we generate jumps to current or next
1324
   instruction */
1325
#define GEN_REPZ(op)                                                          \
1326
static inline void gen_repz_ ## op(DisasContext *s, int ot,                   \
1327
                                 target_ulong cur_eip, target_ulong next_eip) \
1328
{                                                                             \
1329
    int l2;\
1330
    gen_update_cc_op(s);                                                      \
1331
    l2 = gen_jz_ecx_string(s, next_eip);                                      \
1332
    gen_ ## op(s, ot);                                                        \
1333
    gen_op_add_reg_im(s->aflag, R_ECX, -1);                                   \
1334
    /* a loop would cause two single step exceptions if ECX = 1               \
1335
       before rep string_insn */                                              \
1336
    if (!s->jmp_opt)                                                          \
1337
        gen_op_jz_ecx(s->aflag, l2);                                          \
1338
    gen_jmp(s, cur_eip);                                                      \
1339
}
1340

    
1341
#define GEN_REPZ2(op)                                                         \
1342
static inline void gen_repz_ ## op(DisasContext *s, int ot,                   \
1343
                                   target_ulong cur_eip,                      \
1344
                                   target_ulong next_eip,                     \
1345
                                   int nz)                                    \
1346
{                                                                             \
1347
    int l2;\
1348
    gen_update_cc_op(s);                                                      \
1349
    l2 = gen_jz_ecx_string(s, next_eip);                                      \
1350
    gen_ ## op(s, ot);                                                        \
1351
    gen_op_add_reg_im(s->aflag, R_ECX, -1);                                   \
1352
    gen_update_cc_op(s);                                                      \
1353
    gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2);                                 \
1354
    if (!s->jmp_opt)                                                          \
1355
        gen_op_jz_ecx(s->aflag, l2);                                          \
1356
    gen_jmp(s, cur_eip);                                                      \
1357
}
1358

    
1359
GEN_REPZ(movs)
1360
GEN_REPZ(stos)
1361
GEN_REPZ(lods)
1362
GEN_REPZ(ins)
1363
GEN_REPZ(outs)
1364
GEN_REPZ2(scas)
1365
GEN_REPZ2(cmps)
1366

    
1367
static void gen_helper_fp_arith_ST0_FT0(int op)
1368
{
1369
    switch (op) {
1370
    case 0:
1371
        gen_helper_fadd_ST0_FT0(cpu_env);
1372
        break;
1373
    case 1:
1374
        gen_helper_fmul_ST0_FT0(cpu_env);
1375
        break;
1376
    case 2:
1377
        gen_helper_fcom_ST0_FT0(cpu_env);
1378
        break;
1379
    case 3:
1380
        gen_helper_fcom_ST0_FT0(cpu_env);
1381
        break;
1382
    case 4:
1383
        gen_helper_fsub_ST0_FT0(cpu_env);
1384
        break;
1385
    case 5:
1386
        gen_helper_fsubr_ST0_FT0(cpu_env);
1387
        break;
1388
    case 6:
1389
        gen_helper_fdiv_ST0_FT0(cpu_env);
1390
        break;
1391
    case 7:
1392
        gen_helper_fdivr_ST0_FT0(cpu_env);
1393
        break;
1394
    }
1395
}
1396

    
1397
/* NOTE the exception in "r" op ordering */
1398
static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1399
{
1400
    TCGv_i32 tmp = tcg_const_i32(opreg);
1401
    switch (op) {
1402
    case 0:
1403
        gen_helper_fadd_STN_ST0(cpu_env, tmp);
1404
        break;
1405
    case 1:
1406
        gen_helper_fmul_STN_ST0(cpu_env, tmp);
1407
        break;
1408
    case 4:
1409
        gen_helper_fsubr_STN_ST0(cpu_env, tmp);
1410
        break;
1411
    case 5:
1412
        gen_helper_fsub_STN_ST0(cpu_env, tmp);
1413
        break;
1414
    case 6:
1415
        gen_helper_fdivr_STN_ST0(cpu_env, tmp);
1416
        break;
1417
    case 7:
1418
        gen_helper_fdiv_STN_ST0(cpu_env, tmp);
1419
        break;
1420
    }
1421
}
1422

    
1423
/* if d == OR_TMP0, it means memory operand (address in A0) */
1424
static void gen_op(DisasContext *s1, int op, int ot, int d)
1425
{
1426
    if (d != OR_TMP0) {
1427
        gen_op_mov_TN_reg(ot, 0, d);
1428
    } else {
1429
        gen_op_ld_T0_A0(ot + s1->mem_index);
1430
    }
1431
    switch(op) {
1432
    case OP_ADCL:
1433
        gen_compute_eflags_c(s1, cpu_tmp4);
1434
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1435
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
1436
        if (d != OR_TMP0)
1437
            gen_op_mov_reg_T0(ot, d);
1438
        else
1439
            gen_op_st_T0_A0(ot + s1->mem_index);
1440
        gen_op_update3_cc(cpu_tmp4);
1441
        set_cc_op(s1, CC_OP_ADCB + ot);
1442
        break;
1443
    case OP_SBBL:
1444
        gen_compute_eflags_c(s1, cpu_tmp4);
1445
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1446
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
1447
        if (d != OR_TMP0)
1448
            gen_op_mov_reg_T0(ot, d);
1449
        else
1450
            gen_op_st_T0_A0(ot + s1->mem_index);
1451
        gen_op_update3_cc(cpu_tmp4);
1452
        set_cc_op(s1, CC_OP_SBBB + ot);
1453
        break;
1454
    case OP_ADDL:
1455
        gen_op_addl_T0_T1();
1456
        if (d != OR_TMP0)
1457
            gen_op_mov_reg_T0(ot, d);
1458
        else
1459
            gen_op_st_T0_A0(ot + s1->mem_index);
1460
        gen_op_update2_cc();
1461
        set_cc_op(s1, CC_OP_ADDB + ot);
1462
        break;
1463
    case OP_SUBL:
1464
        tcg_gen_mov_tl(cpu_cc_srcT, cpu_T[0]);
1465
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1466
        if (d != OR_TMP0)
1467
            gen_op_mov_reg_T0(ot, d);
1468
        else
1469
            gen_op_st_T0_A0(ot + s1->mem_index);
1470
        gen_op_update2_cc();
1471
        set_cc_op(s1, CC_OP_SUBB + ot);
1472
        break;
1473
    default:
1474
    case OP_ANDL:
1475
        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
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_update1_cc();
1481
        set_cc_op(s1, CC_OP_LOGICB + ot);
1482
        break;
1483
    case OP_ORL:
1484
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1485
        if (d != OR_TMP0)
1486
            gen_op_mov_reg_T0(ot, d);
1487
        else
1488
            gen_op_st_T0_A0(ot + s1->mem_index);
1489
        gen_op_update1_cc();
1490
        set_cc_op(s1, CC_OP_LOGICB + ot);
1491
        break;
1492
    case OP_XORL:
1493
        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1494
        if (d != OR_TMP0)
1495
            gen_op_mov_reg_T0(ot, d);
1496
        else
1497
            gen_op_st_T0_A0(ot + s1->mem_index);
1498
        gen_op_update1_cc();
1499
        set_cc_op(s1, CC_OP_LOGICB + ot);
1500
        break;
1501
    case OP_CMPL:
1502
        tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
1503
        tcg_gen_mov_tl(cpu_cc_srcT, cpu_T[0]);
1504
        tcg_gen_sub_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
1505
        set_cc_op(s1, CC_OP_SUBB + ot);
1506
        break;
1507
    }
1508
}
1509

    
1510
/* if d == OR_TMP0, it means memory operand (address in A0) */
1511
static void gen_inc(DisasContext *s1, int ot, int d, int c)
1512
{
1513
    if (d != OR_TMP0)
1514
        gen_op_mov_TN_reg(ot, 0, d);
1515
    else
1516
        gen_op_ld_T0_A0(ot + s1->mem_index);
1517
    gen_compute_eflags_c(s1, cpu_cc_src);
1518
    if (c > 0) {
1519
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 1);
1520
        set_cc_op(s1, CC_OP_INCB + ot);
1521
    } else {
1522
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], -1);
1523
        set_cc_op(s1, CC_OP_DECB + ot);
1524
    }
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
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1530
}
1531

    
1532
static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, 
1533
                            int is_right, int is_arith)
1534
{
1535
    target_ulong mask;
1536
    int shift_label;
1537
    TCGv t0, t1, t2;
1538

    
1539
    if (ot == OT_QUAD) {
1540
        mask = 0x3f;
1541
    } else {
1542
        mask = 0x1f;
1543
    }
1544

    
1545
    /* load */
1546
    if (op1 == OR_TMP0) {
1547
        gen_op_ld_T0_A0(ot + s->mem_index);
1548
    } else {
1549
        gen_op_mov_TN_reg(ot, 0, op1);
1550
    }
1551

    
1552
    t0 = tcg_temp_local_new();
1553
    t1 = tcg_temp_local_new();
1554
    t2 = tcg_temp_local_new();
1555

    
1556
    tcg_gen_andi_tl(t2, cpu_T[1], mask);
1557

    
1558
    if (is_right) {
1559
        if (is_arith) {
1560
            gen_exts(ot, cpu_T[0]);
1561
            tcg_gen_mov_tl(t0, cpu_T[0]);
1562
            tcg_gen_sar_tl(cpu_T[0], cpu_T[0], t2);
1563
        } else {
1564
            gen_extu(ot, cpu_T[0]);
1565
            tcg_gen_mov_tl(t0, cpu_T[0]);
1566
            tcg_gen_shr_tl(cpu_T[0], cpu_T[0], t2);
1567
        }
1568
    } else {
1569
        tcg_gen_mov_tl(t0, cpu_T[0]);
1570
        tcg_gen_shl_tl(cpu_T[0], cpu_T[0], t2);
1571
    }
1572

    
1573
    /* store */
1574
    if (op1 == OR_TMP0) {
1575
        gen_op_st_T0_A0(ot + s->mem_index);
1576
    } else {
1577
        gen_op_mov_reg_T0(ot, op1);
1578
    }
1579

    
1580
    /* Update eflags data because we cannot predict flags afterward.  */
1581
    gen_update_cc_op(s);
1582
    set_cc_op(s, CC_OP_DYNAMIC);
1583

    
1584
    tcg_gen_mov_tl(t1, cpu_T[0]);
1585

    
1586
    shift_label = gen_new_label();
1587
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, shift_label);
1588

    
1589
    tcg_gen_addi_tl(t2, t2, -1);
1590
    tcg_gen_mov_tl(cpu_cc_dst, t1);
1591

    
1592
    if (is_right) {
1593
        if (is_arith) {
1594
            tcg_gen_sar_tl(cpu_cc_src, t0, t2);
1595
        } else {
1596
            tcg_gen_shr_tl(cpu_cc_src, t0, t2);
1597
        }
1598
    } else {
1599
        tcg_gen_shl_tl(cpu_cc_src, t0, t2);
1600
    }
1601

    
1602
    if (is_right) {
1603
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
1604
    } else {
1605
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
1606
    }
1607

    
1608
    gen_set_label(shift_label);
1609

    
1610
    tcg_temp_free(t0);
1611
    tcg_temp_free(t1);
1612
    tcg_temp_free(t2);
1613
}
1614

    
1615
static void gen_shift_rm_im(DisasContext *s, int ot, int op1, int op2,
1616
                            int is_right, int is_arith)
1617
{
1618
    int mask;
1619
    
1620
    if (ot == OT_QUAD)
1621
        mask = 0x3f;
1622
    else
1623
        mask = 0x1f;
1624

    
1625
    /* load */
1626
    if (op1 == OR_TMP0)
1627
        gen_op_ld_T0_A0(ot + s->mem_index);
1628
    else
1629
        gen_op_mov_TN_reg(ot, 0, op1);
1630

    
1631
    op2 &= mask;
1632
    if (op2 != 0) {
1633
        if (is_right) {
1634
            if (is_arith) {
1635
                gen_exts(ot, cpu_T[0]);
1636
                tcg_gen_sari_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1637
                tcg_gen_sari_tl(cpu_T[0], cpu_T[0], op2);
1638
            } else {
1639
                gen_extu(ot, cpu_T[0]);
1640
                tcg_gen_shri_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1641
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], op2);
1642
            }
1643
        } else {
1644
            tcg_gen_shli_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1645
            tcg_gen_shli_tl(cpu_T[0], cpu_T[0], op2);
1646
        }
1647
    }
1648

    
1649
    /* store */
1650
    if (op1 == OR_TMP0)
1651
        gen_op_st_T0_A0(ot + s->mem_index);
1652
    else
1653
        gen_op_mov_reg_T0(ot, op1);
1654
        
1655
    /* update eflags if non zero shift */
1656
    if (op2 != 0) {
1657
        tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
1658
        tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1659
        set_cc_op(s, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1660
    }
1661
}
1662

    
1663
static inline void tcg_gen_lshift(TCGv ret, TCGv arg1, target_long arg2)
1664
{
1665
    if (arg2 >= 0)
1666
        tcg_gen_shli_tl(ret, arg1, arg2);
1667
    else
1668
        tcg_gen_shri_tl(ret, arg1, -arg2);
1669
}
1670

    
1671
static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, 
1672
                          int is_right)
1673
{
1674
    target_ulong mask;
1675
    int label1, label2, data_bits;
1676
    TCGv t0, t1, t2, a0;
1677

    
1678
    /* XXX: inefficient, but we must use local temps */
1679
    t0 = tcg_temp_local_new();
1680
    t1 = tcg_temp_local_new();
1681
    t2 = tcg_temp_local_new();
1682
    a0 = tcg_temp_local_new();
1683

    
1684
    if (ot == OT_QUAD)
1685
        mask = 0x3f;
1686
    else
1687
        mask = 0x1f;
1688

    
1689
    /* load */
1690
    if (op1 == OR_TMP0) {
1691
        tcg_gen_mov_tl(a0, cpu_A0);
1692
        gen_op_ld_v(ot + s->mem_index, t0, a0);
1693
    } else {
1694
        gen_op_mov_v_reg(ot, t0, op1);
1695
    }
1696

    
1697
    tcg_gen_mov_tl(t1, cpu_T[1]);
1698

    
1699
    tcg_gen_andi_tl(t1, t1, mask);
1700

    
1701
    /* Must test zero case to avoid using undefined behaviour in TCG
1702
       shifts. */
1703
    label1 = gen_new_label();
1704
    tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label1);
1705
    
1706
    if (ot <= OT_WORD)
1707
        tcg_gen_andi_tl(cpu_tmp0, t1, (1 << (3 + ot)) - 1);
1708
    else
1709
        tcg_gen_mov_tl(cpu_tmp0, t1);
1710
    
1711
    gen_extu(ot, t0);
1712
    tcg_gen_mov_tl(t2, t0);
1713

    
1714
    data_bits = 8 << ot;
1715
    /* XXX: rely on behaviour of shifts when operand 2 overflows (XXX:
1716
       fix TCG definition) */
1717
    if (is_right) {
1718
        tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp0);
1719
        tcg_gen_subfi_tl(cpu_tmp0, data_bits, cpu_tmp0);
1720
        tcg_gen_shl_tl(t0, t0, cpu_tmp0);
1721
    } else {
1722
        tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp0);
1723
        tcg_gen_subfi_tl(cpu_tmp0, data_bits, cpu_tmp0);
1724
        tcg_gen_shr_tl(t0, t0, cpu_tmp0);
1725
    }
1726
    tcg_gen_or_tl(t0, t0, cpu_tmp4);
1727

    
1728
    gen_set_label(label1);
1729
    /* store */
1730
    if (op1 == OR_TMP0) {
1731
        gen_op_st_v(ot + s->mem_index, t0, a0);
1732
    } else {
1733
        gen_op_mov_reg_v(ot, op1, t0);
1734
    }
1735
    
1736
    /* update eflags.  It is needed anyway most of the time, do it always.  */
1737
    gen_compute_eflags(s);
1738
    assert(s->cc_op == CC_OP_EFLAGS);
1739

    
1740
    label2 = gen_new_label();
1741
    tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label2);
1742

    
1743
    tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
1744
    tcg_gen_xor_tl(cpu_tmp0, t2, t0);
1745
    tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
1746
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
1747
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
1748
    if (is_right) {
1749
        tcg_gen_shri_tl(t0, t0, data_bits - 1);
1750
    }
1751
    tcg_gen_andi_tl(t0, t0, CC_C);
1752
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
1753

    
1754
    gen_set_label(label2);
1755

    
1756
    tcg_temp_free(t0);
1757
    tcg_temp_free(t1);
1758
    tcg_temp_free(t2);
1759
    tcg_temp_free(a0);
1760
}
1761

    
1762
static void gen_rot_rm_im(DisasContext *s, int ot, int op1, int op2,
1763
                          int is_right)
1764
{
1765
    int mask;
1766
    int data_bits;
1767
    TCGv t0, t1, a0;
1768

    
1769
    /* XXX: inefficient, but we must use local temps */
1770
    t0 = tcg_temp_local_new();
1771
    t1 = tcg_temp_local_new();
1772
    a0 = tcg_temp_local_new();
1773

    
1774
    if (ot == OT_QUAD)
1775
        mask = 0x3f;
1776
    else
1777
        mask = 0x1f;
1778

    
1779
    /* load */
1780
    if (op1 == OR_TMP0) {
1781
        tcg_gen_mov_tl(a0, cpu_A0);
1782
        gen_op_ld_v(ot + s->mem_index, t0, a0);
1783
    } else {
1784
        gen_op_mov_v_reg(ot, t0, op1);
1785
    }
1786

    
1787
    gen_extu(ot, t0);
1788
    tcg_gen_mov_tl(t1, t0);
1789

    
1790
    op2 &= mask;
1791
    data_bits = 8 << ot;
1792
    if (op2 != 0) {
1793
        int shift = op2 & ((1 << (3 + ot)) - 1);
1794
        if (is_right) {
1795
            tcg_gen_shri_tl(cpu_tmp4, t0, shift);
1796
            tcg_gen_shli_tl(t0, t0, data_bits - shift);
1797
        }
1798
        else {
1799
            tcg_gen_shli_tl(cpu_tmp4, t0, shift);
1800
            tcg_gen_shri_tl(t0, t0, data_bits - shift);
1801
        }
1802
        tcg_gen_or_tl(t0, t0, cpu_tmp4);
1803
    }
1804

    
1805
    /* store */
1806
    if (op1 == OR_TMP0) {
1807
        gen_op_st_v(ot + s->mem_index, t0, a0);
1808
    } else {
1809
        gen_op_mov_reg_v(ot, op1, t0);
1810
    }
1811

    
1812
    if (op2 != 0) {
1813
        /* update eflags */
1814
        gen_compute_eflags(s);
1815
        assert(s->cc_op == CC_OP_EFLAGS);
1816

    
1817
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
1818
        tcg_gen_xor_tl(cpu_tmp0, t1, t0);
1819
        tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
1820
        tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
1821
        tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
1822
        if (is_right) {
1823
            tcg_gen_shri_tl(t0, t0, data_bits - 1);
1824
        }
1825
        tcg_gen_andi_tl(t0, t0, CC_C);
1826
        tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
1827
    }
1828

    
1829
    tcg_temp_free(t0);
1830
    tcg_temp_free(t1);
1831
    tcg_temp_free(a0);
1832
}
1833

    
1834
/* XXX: add faster immediate = 1 case */
1835
static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, 
1836
                           int is_right)
1837
{
1838
    gen_compute_eflags(s);
1839
    assert(s->cc_op == CC_OP_EFLAGS);
1840

    
1841
    /* load */
1842
    if (op1 == OR_TMP0)
1843
        gen_op_ld_T0_A0(ot + s->mem_index);
1844
    else
1845
        gen_op_mov_TN_reg(ot, 0, op1);
1846
    
1847
    if (is_right) {
1848
        switch (ot) {
1849
        case OT_BYTE:
1850
            gen_helper_rcrb(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1851
            break;
1852
        case OT_WORD:
1853
            gen_helper_rcrw(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1854
            break;
1855
        case OT_LONG:
1856
            gen_helper_rcrl(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1857
            break;
1858
#ifdef TARGET_X86_64
1859
        case OT_QUAD:
1860
            gen_helper_rcrq(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1861
            break;
1862
#endif
1863
        }
1864
    } else {
1865
        switch (ot) {
1866
        case OT_BYTE:
1867
            gen_helper_rclb(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1868
            break;
1869
        case OT_WORD:
1870
            gen_helper_rclw(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1871
            break;
1872
        case OT_LONG:
1873
            gen_helper_rcll(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1874
            break;
1875
#ifdef TARGET_X86_64
1876
        case OT_QUAD:
1877
            gen_helper_rclq(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1878
            break;
1879
#endif
1880
        }
1881
    }
1882
    /* store */
1883
    if (op1 == OR_TMP0)
1884
        gen_op_st_T0_A0(ot + s->mem_index);
1885
    else
1886
        gen_op_mov_reg_T0(ot, op1);
1887
}
1888

    
1889
/* XXX: add faster immediate case */
1890
static void gen_shiftd_rm_T1(DisasContext *s, int ot, int op1,
1891
                             int is_right, TCGv count)
1892
{
1893
    int label1, label2, data_bits;
1894
    target_ulong mask;
1895
    TCGv t0, t1, t2, a0;
1896

    
1897
    t0 = tcg_temp_local_new();
1898
    t1 = tcg_temp_local_new();
1899
    t2 = tcg_temp_local_new();
1900
    a0 = tcg_temp_local_new();
1901

    
1902
    if (ot == OT_QUAD)
1903
        mask = 0x3f;
1904
    else
1905
        mask = 0x1f;
1906

    
1907
    /* load */
1908
    if (op1 == OR_TMP0) {
1909
        tcg_gen_mov_tl(a0, cpu_A0);
1910
        gen_op_ld_v(ot + s->mem_index, t0, a0);
1911
    } else {
1912
        gen_op_mov_v_reg(ot, t0, op1);
1913
    }
1914

    
1915
    tcg_gen_andi_tl(t2, count, mask);
1916
    tcg_gen_mov_tl(t1, cpu_T[1]);
1917

    
1918
    /* Must test zero case to avoid using undefined behaviour in TCG
1919
       shifts. */
1920
    label1 = gen_new_label();
1921
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
1922
    
1923
    tcg_gen_addi_tl(cpu_tmp5, t2, -1);
1924
    if (ot == OT_WORD) {
1925
        /* Note: we implement the Intel behaviour for shift count > 16 */
1926
        if (is_right) {
1927
            tcg_gen_andi_tl(t0, t0, 0xffff);
1928
            tcg_gen_shli_tl(cpu_tmp0, t1, 16);
1929
            tcg_gen_or_tl(t0, t0, cpu_tmp0);
1930
            tcg_gen_ext32u_tl(t0, t0);
1931

    
1932
            tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
1933
            
1934
            /* only needed if count > 16, but a test would complicate */
1935
            tcg_gen_subfi_tl(cpu_tmp5, 32, t2);
1936
            tcg_gen_shl_tl(cpu_tmp0, t0, cpu_tmp5);
1937

    
1938
            tcg_gen_shr_tl(t0, t0, t2);
1939

    
1940
            tcg_gen_or_tl(t0, t0, cpu_tmp0);
1941
        } else {
1942
            /* XXX: not optimal */
1943
            tcg_gen_andi_tl(t0, t0, 0xffff);
1944
            tcg_gen_shli_tl(t1, t1, 16);
1945
            tcg_gen_or_tl(t1, t1, t0);
1946
            tcg_gen_ext32u_tl(t1, t1);
1947
            
1948
            tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
1949
            tcg_gen_subfi_tl(cpu_tmp0, 32, cpu_tmp5);
1950
            tcg_gen_shr_tl(cpu_tmp5, t1, cpu_tmp0);
1951
            tcg_gen_or_tl(cpu_tmp4, cpu_tmp4, cpu_tmp5);
1952

    
1953
            tcg_gen_shl_tl(t0, t0, t2);
1954
            tcg_gen_subfi_tl(cpu_tmp5, 32, t2);
1955
            tcg_gen_shr_tl(t1, t1, cpu_tmp5);
1956
            tcg_gen_or_tl(t0, t0, t1);
1957
        }
1958
    } else {
1959
        data_bits = 8 << ot;
1960
        if (is_right) {
1961
            if (ot == OT_LONG)
1962
                tcg_gen_ext32u_tl(t0, t0);
1963

    
1964
            tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
1965

    
1966
            tcg_gen_shr_tl(t0, t0, t2);
1967
            tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2);
1968
            tcg_gen_shl_tl(t1, t1, cpu_tmp5);
1969
            tcg_gen_or_tl(t0, t0, t1);
1970
            
1971
        } else {
1972
            if (ot == OT_LONG)
1973
                tcg_gen_ext32u_tl(t1, t1);
1974

    
1975
            tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
1976
            
1977
            tcg_gen_shl_tl(t0, t0, t2);
1978
            tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2);
1979
            tcg_gen_shr_tl(t1, t1, cpu_tmp5);
1980
            tcg_gen_or_tl(t0, t0, t1);
1981
        }
1982
    }
1983
    tcg_gen_mov_tl(t1, cpu_tmp4);
1984

    
1985
    gen_set_label(label1);
1986
    /* store */
1987
    if (op1 == OR_TMP0) {
1988
        gen_op_st_v(ot + s->mem_index, t0, a0);
1989
    } else {
1990
        gen_op_mov_reg_v(ot, op1, t0);
1991
    }
1992
    
1993
    /* Update eflags data because we cannot predict flags afterward.  */
1994
    gen_update_cc_op(s);
1995
    set_cc_op(s, CC_OP_DYNAMIC);
1996

    
1997
    label2 = gen_new_label();
1998
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label2);
1999

    
2000
    tcg_gen_mov_tl(cpu_cc_src, t1);
2001
    tcg_gen_mov_tl(cpu_cc_dst, t0);
2002
    if (is_right) {
2003
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
2004
    } else {
2005
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
2006
    }
2007
    gen_set_label(label2);
2008

    
2009
    tcg_temp_free(t0);
2010
    tcg_temp_free(t1);
2011
    tcg_temp_free(t2);
2012
    tcg_temp_free(a0);
2013
}
2014

    
2015
static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
2016
{
2017
    if (s != OR_TMP1)
2018
        gen_op_mov_TN_reg(ot, 1, s);
2019
    switch(op) {
2020
    case OP_ROL:
2021
        gen_rot_rm_T1(s1, ot, d, 0);
2022
        break;
2023
    case OP_ROR:
2024
        gen_rot_rm_T1(s1, ot, d, 1);
2025
        break;
2026
    case OP_SHL:
2027
    case OP_SHL1:
2028
        gen_shift_rm_T1(s1, ot, d, 0, 0);
2029
        break;
2030
    case OP_SHR:
2031
        gen_shift_rm_T1(s1, ot, d, 1, 0);
2032
        break;
2033
    case OP_SAR:
2034
        gen_shift_rm_T1(s1, ot, d, 1, 1);
2035
        break;
2036
    case OP_RCL:
2037
        gen_rotc_rm_T1(s1, ot, d, 0);
2038
        break;
2039
    case OP_RCR:
2040
        gen_rotc_rm_T1(s1, ot, d, 1);
2041
        break;
2042
    }
2043
}
2044

    
2045
static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
2046
{
2047
    switch(op) {
2048
    case OP_ROL:
2049
        gen_rot_rm_im(s1, ot, d, c, 0);
2050
        break;
2051
    case OP_ROR:
2052
        gen_rot_rm_im(s1, ot, d, c, 1);
2053
        break;
2054
    case OP_SHL:
2055
    case OP_SHL1:
2056
        gen_shift_rm_im(s1, ot, d, c, 0, 0);
2057
        break;
2058
    case OP_SHR:
2059
        gen_shift_rm_im(s1, ot, d, c, 1, 0);
2060
        break;
2061
    case OP_SAR:
2062
        gen_shift_rm_im(s1, ot, d, c, 1, 1);
2063
        break;
2064
    default:
2065
        /* currently not optimized */
2066
        gen_op_movl_T1_im(c);
2067
        gen_shift(s1, op, ot, d, OR_TMP1);
2068
        break;
2069
    }
2070
}
2071

    
2072
static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm,
2073
                          int *reg_ptr, int *offset_ptr)
2074
{
2075
    target_long disp;
2076
    int havesib;
2077
    int base;
2078
    int index;
2079
    int scale;
2080
    int opreg;
2081
    int mod, rm, code, override, must_add_seg;
2082

    
2083
    override = s->override;
2084
    must_add_seg = s->addseg;
2085
    if (override >= 0)
2086
        must_add_seg = 1;
2087
    mod = (modrm >> 6) & 3;
2088
    rm = modrm & 7;
2089

    
2090
    if (s->aflag) {
2091

    
2092
        havesib = 0;
2093
        base = rm;
2094
        index = 0;
2095
        scale = 0;
2096

    
2097
        if (base == 4) {
2098
            havesib = 1;
2099
            code = cpu_ldub_code(env, s->pc++);
2100
            scale = (code >> 6) & 3;
2101
            index = ((code >> 3) & 7) | REX_X(s);
2102
            base = (code & 7);
2103
        }
2104
        base |= REX_B(s);
2105

    
2106
        switch (mod) {
2107
        case 0:
2108
            if ((base & 7) == 5) {
2109
                base = -1;
2110
                disp = (int32_t)cpu_ldl_code(env, s->pc);
2111
                s->pc += 4;
2112
                if (CODE64(s) && !havesib) {
2113
                    disp += s->pc + s->rip_offset;
2114
                }
2115
            } else {
2116
                disp = 0;
2117
            }
2118
            break;
2119
        case 1:
2120
            disp = (int8_t)cpu_ldub_code(env, s->pc++);
2121
            break;
2122
        default:
2123
        case 2:
2124
            disp = (int32_t)cpu_ldl_code(env, s->pc);
2125
            s->pc += 4;
2126
            break;
2127
        }
2128

    
2129
        if (base >= 0) {
2130
            /* for correct popl handling with esp */
2131
            if (base == 4 && s->popl_esp_hack)
2132
                disp += s->popl_esp_hack;
2133
#ifdef TARGET_X86_64
2134
            if (s->aflag == 2) {
2135
                gen_op_movq_A0_reg(base);
2136
                if (disp != 0) {
2137
                    gen_op_addq_A0_im(disp);
2138
                }
2139
            } else
2140
#endif
2141
            {
2142
                gen_op_movl_A0_reg(base);
2143
                if (disp != 0)
2144
                    gen_op_addl_A0_im(disp);
2145
            }
2146
        } else {
2147
#ifdef TARGET_X86_64
2148
            if (s->aflag == 2) {
2149
                gen_op_movq_A0_im(disp);
2150
            } else
2151
#endif
2152
            {
2153
                gen_op_movl_A0_im(disp);
2154
            }
2155
        }
2156
        /* index == 4 means no index */
2157
        if (havesib && (index != 4)) {
2158
#ifdef TARGET_X86_64
2159
            if (s->aflag == 2) {
2160
                gen_op_addq_A0_reg_sN(scale, index);
2161
            } else
2162
#endif
2163
            {
2164
                gen_op_addl_A0_reg_sN(scale, index);
2165
            }
2166
        }
2167
        if (must_add_seg) {
2168
            if (override < 0) {
2169
                if (base == R_EBP || base == R_ESP)
2170
                    override = R_SS;
2171
                else
2172
                    override = R_DS;
2173
            }
2174
#ifdef TARGET_X86_64
2175
            if (s->aflag == 2) {
2176
                gen_op_addq_A0_seg(override);
2177
            } else
2178
#endif
2179
            {
2180
                gen_op_addl_A0_seg(s, override);
2181
            }
2182
        }
2183
    } else {
2184
        switch (mod) {
2185
        case 0:
2186
            if (rm == 6) {
2187
                disp = cpu_lduw_code(env, s->pc);
2188
                s->pc += 2;
2189
                gen_op_movl_A0_im(disp);
2190
                rm = 0; /* avoid SS override */
2191
                goto no_rm;
2192
            } else {
2193
                disp = 0;
2194
            }
2195
            break;
2196
        case 1:
2197
            disp = (int8_t)cpu_ldub_code(env, s->pc++);
2198
            break;
2199
        default:
2200
        case 2:
2201
            disp = cpu_lduw_code(env, s->pc);
2202
            s->pc += 2;
2203
            break;
2204
        }
2205
        switch(rm) {
2206
        case 0:
2207
            gen_op_movl_A0_reg(R_EBX);
2208
            gen_op_addl_A0_reg_sN(0, R_ESI);
2209
            break;
2210
        case 1:
2211
            gen_op_movl_A0_reg(R_EBX);
2212
            gen_op_addl_A0_reg_sN(0, R_EDI);
2213
            break;
2214
        case 2:
2215
            gen_op_movl_A0_reg(R_EBP);
2216
            gen_op_addl_A0_reg_sN(0, R_ESI);
2217
            break;
2218
        case 3:
2219
            gen_op_movl_A0_reg(R_EBP);
2220
            gen_op_addl_A0_reg_sN(0, R_EDI);
2221
            break;
2222
        case 4:
2223
            gen_op_movl_A0_reg(R_ESI);
2224
            break;
2225
        case 5:
2226
            gen_op_movl_A0_reg(R_EDI);
2227
            break;
2228
        case 6:
2229
            gen_op_movl_A0_reg(R_EBP);
2230
            break;
2231
        default:
2232
        case 7:
2233
            gen_op_movl_A0_reg(R_EBX);
2234
            break;
2235
        }
2236
        if (disp != 0)
2237
            gen_op_addl_A0_im(disp);
2238
        gen_op_andl_A0_ffff();
2239
    no_rm:
2240
        if (must_add_seg) {
2241
            if (override < 0) {
2242
                if (rm == 2 || rm == 3 || rm == 6)
2243
                    override = R_SS;
2244
                else
2245
                    override = R_DS;
2246
            }
2247
            gen_op_addl_A0_seg(s, override);
2248
        }
2249
    }
2250

    
2251
    opreg = OR_A0;
2252
    disp = 0;
2253
    *reg_ptr = opreg;
2254
    *offset_ptr = disp;
2255
}
2256

    
2257
static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
2258
{
2259
    int mod, rm, base, code;
2260

    
2261
    mod = (modrm >> 6) & 3;
2262
    if (mod == 3)
2263
        return;
2264
    rm = modrm & 7;
2265

    
2266
    if (s->aflag) {
2267

    
2268
        base = rm;
2269

    
2270
        if (base == 4) {
2271
            code = cpu_ldub_code(env, s->pc++);
2272
            base = (code & 7);
2273
        }
2274

    
2275
        switch (mod) {
2276
        case 0:
2277
            if (base == 5) {
2278
                s->pc += 4;
2279
            }
2280
            break;
2281
        case 1:
2282
            s->pc++;
2283
            break;
2284
        default:
2285
        case 2:
2286
            s->pc += 4;
2287
            break;
2288
        }
2289
    } else {
2290
        switch (mod) {
2291
        case 0:
2292
            if (rm == 6) {
2293
                s->pc += 2;
2294
            }
2295
            break;
2296
        case 1:
2297
            s->pc++;
2298
            break;
2299
        default:
2300
        case 2:
2301
            s->pc += 2;
2302
            break;
2303
        }
2304
    }
2305
}
2306

    
2307
/* used for LEA and MOV AX, mem */
2308
static void gen_add_A0_ds_seg(DisasContext *s)
2309
{
2310
    int override, must_add_seg;
2311
    must_add_seg = s->addseg;
2312
    override = R_DS;
2313
    if (s->override >= 0) {
2314
        override = s->override;
2315
        must_add_seg = 1;
2316
    }
2317
    if (must_add_seg) {
2318
#ifdef TARGET_X86_64
2319
        if (CODE64(s)) {
2320
            gen_op_addq_A0_seg(override);
2321
        } else
2322
#endif
2323
        {
2324
            gen_op_addl_A0_seg(s, override);
2325
        }
2326
    }
2327
}
2328

    
2329
/* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2330
   OR_TMP0 */
2331
static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm,
2332
                           int ot, int reg, int is_store)
2333
{
2334
    int mod, rm, opreg, disp;
2335

    
2336
    mod = (modrm >> 6) & 3;
2337
    rm = (modrm & 7) | REX_B(s);
2338
    if (mod == 3) {
2339
        if (is_store) {
2340
            if (reg != OR_TMP0)
2341
                gen_op_mov_TN_reg(ot, 0, reg);
2342
            gen_op_mov_reg_T0(ot, rm);
2343
        } else {
2344
            gen_op_mov_TN_reg(ot, 0, rm);
2345
            if (reg != OR_TMP0)
2346
                gen_op_mov_reg_T0(ot, reg);
2347
        }
2348
    } else {
2349
        gen_lea_modrm(env, s, modrm, &opreg, &disp);
2350
        if (is_store) {
2351
            if (reg != OR_TMP0)
2352
                gen_op_mov_TN_reg(ot, 0, reg);
2353
            gen_op_st_T0_A0(ot + s->mem_index);
2354
        } else {
2355
            gen_op_ld_T0_A0(ot + s->mem_index);
2356
            if (reg != OR_TMP0)
2357
                gen_op_mov_reg_T0(ot, reg);
2358
        }
2359
    }
2360
}
2361

    
2362
static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, int ot)
2363
{
2364
    uint32_t ret;
2365

    
2366
    switch(ot) {
2367
    case OT_BYTE:
2368
        ret = cpu_ldub_code(env, s->pc);
2369
        s->pc++;
2370
        break;
2371
    case OT_WORD:
2372
        ret = cpu_lduw_code(env, s->pc);
2373
        s->pc += 2;
2374
        break;
2375
    default:
2376
    case OT_LONG:
2377
        ret = cpu_ldl_code(env, s->pc);
2378
        s->pc += 4;
2379
        break;
2380
    }
2381
    return ret;
2382
}
2383

    
2384
static inline int insn_const_size(unsigned int ot)
2385
{
2386
    if (ot <= OT_LONG)
2387
        return 1 << ot;
2388
    else
2389
        return 4;
2390
}
2391

    
2392
static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
2393
{
2394
    TranslationBlock *tb;
2395
    target_ulong pc;
2396

    
2397
    pc = s->cs_base + eip;
2398
    tb = s->tb;
2399
    /* NOTE: we handle the case where the TB spans two pages here */
2400
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
2401
        (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
2402
        /* jump to same page: we can use a direct jump */
2403
        tcg_gen_goto_tb(tb_num);
2404
        gen_jmp_im(eip);
2405
        tcg_gen_exit_tb((tcg_target_long)tb + tb_num);
2406
    } else {
2407
        /* jump to another page: currently not optimized */
2408
        gen_jmp_im(eip);
2409
        gen_eob(s);
2410
    }
2411
}
2412

    
2413
static inline void gen_jcc(DisasContext *s, int b,
2414
                           target_ulong val, target_ulong next_eip)
2415
{
2416
    int l1, l2;
2417

    
2418
    if (s->jmp_opt) {
2419
        l1 = gen_new_label();
2420
        gen_jcc1(s, b, l1);
2421

    
2422
        gen_goto_tb(s, 0, next_eip);
2423

    
2424
        gen_set_label(l1);
2425
        gen_goto_tb(s, 1, val);
2426
        s->is_jmp = DISAS_TB_JUMP;
2427
    } else {
2428
        l1 = gen_new_label();
2429
        l2 = gen_new_label();
2430
        gen_jcc1(s, b, l1);
2431

    
2432
        gen_jmp_im(next_eip);
2433
        tcg_gen_br(l2);
2434

    
2435
        gen_set_label(l1);
2436
        gen_jmp_im(val);
2437
        gen_set_label(l2);
2438
        gen_eob(s);
2439
    }
2440
}
2441

    
2442
static void gen_cmovcc1(CPUX86State *env, DisasContext *s, int ot, int b,
2443
                        int modrm, int reg)
2444
{
2445
    CCPrepare cc;
2446

    
2447
    gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
2448

    
2449
    cc = gen_prepare_cc(s, b, cpu_T[1]);
2450
    if (cc.mask != -1) {
2451
        TCGv t0 = tcg_temp_new();
2452
        tcg_gen_andi_tl(t0, cc.reg, cc.mask);
2453
        cc.reg = t0;
2454
    }
2455
    if (!cc.use_reg2) {
2456
        cc.reg2 = tcg_const_tl(cc.imm);
2457
    }
2458

    
2459
    tcg_gen_movcond_tl(cc.cond, cpu_T[0], cc.reg, cc.reg2,
2460
                       cpu_T[0], cpu_regs[reg]);
2461
    gen_op_mov_reg_T0(ot, reg);
2462

    
2463
    if (cc.mask != -1) {
2464
        tcg_temp_free(cc.reg);
2465
    }
2466
    if (!cc.use_reg2) {
2467
        tcg_temp_free(cc.reg2);
2468
    }
2469
}
2470

    
2471
static inline void gen_op_movl_T0_seg(int seg_reg)
2472
{
2473
    tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
2474
                     offsetof(CPUX86State,segs[seg_reg].selector));
2475
}
2476

    
2477
static inline void gen_op_movl_seg_T0_vm(int seg_reg)
2478
{
2479
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
2480
    tcg_gen_st32_tl(cpu_T[0], cpu_env, 
2481
                    offsetof(CPUX86State,segs[seg_reg].selector));
2482
    tcg_gen_shli_tl(cpu_T[0], cpu_T[0], 4);
2483
    tcg_gen_st_tl(cpu_T[0], cpu_env, 
2484
                  offsetof(CPUX86State,segs[seg_reg].base));
2485
}
2486

    
2487
/* move T0 to seg_reg and compute if the CPU state may change. Never
2488
   call this function with seg_reg == R_CS */
2489
static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
2490
{
2491
    if (s->pe && !s->vm86) {
2492
        /* XXX: optimize by finding processor state dynamically */
2493
        gen_update_cc_op(s);
2494
        gen_jmp_im(cur_eip);
2495
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
2496
        gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), cpu_tmp2_i32);
2497
        /* abort translation because the addseg value may change or
2498
           because ss32 may change. For R_SS, translation must always
2499
           stop as a special handling must be done to disable hardware
2500
           interrupts for the next instruction */
2501
        if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
2502
            s->is_jmp = DISAS_TB_JUMP;
2503
    } else {
2504
        gen_op_movl_seg_T0_vm(seg_reg);
2505
        if (seg_reg == R_SS)
2506
            s->is_jmp = DISAS_TB_JUMP;
2507
    }
2508
}
2509

    
2510
static inline int svm_is_rep(int prefixes)
2511
{
2512
    return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
2513
}
2514

    
2515
static inline void
2516
gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2517
                              uint32_t type, uint64_t param)
2518
{
2519
    /* no SVM activated; fast case */
2520
    if (likely(!(s->flags & HF_SVMI_MASK)))
2521
        return;
2522
    gen_update_cc_op(s);
2523
    gen_jmp_im(pc_start - s->cs_base);
2524
    gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type),
2525
                                         tcg_const_i64(param));
2526
}
2527

    
2528
static inline void
2529
gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
2530
{
2531
    gen_svm_check_intercept_param(s, pc_start, type, 0);
2532
}
2533

    
2534
static inline void gen_stack_update(DisasContext *s, int addend)
2535
{
2536
#ifdef TARGET_X86_64
2537
    if (CODE64(s)) {
2538
        gen_op_add_reg_im(2, R_ESP, addend);
2539
    } else
2540
#endif
2541
    if (s->ss32) {
2542
        gen_op_add_reg_im(1, R_ESP, addend);
2543
    } else {
2544
        gen_op_add_reg_im(0, R_ESP, addend);
2545
    }
2546
}
2547

    
2548
/* generate a push. It depends on ss32, addseg and dflag */
2549
static void gen_push_T0(DisasContext *s)
2550
{
2551
#ifdef TARGET_X86_64
2552
    if (CODE64(s)) {
2553
        gen_op_movq_A0_reg(R_ESP);
2554
        if (s->dflag) {
2555
            gen_op_addq_A0_im(-8);
2556
            gen_op_st_T0_A0(OT_QUAD + s->mem_index);
2557
        } else {
2558
            gen_op_addq_A0_im(-2);
2559
            gen_op_st_T0_A0(OT_WORD + s->mem_index);
2560
        }
2561
        gen_op_mov_reg_A0(2, R_ESP);
2562
    } else
2563
#endif
2564
    {
2565
        gen_op_movl_A0_reg(R_ESP);
2566
        if (!s->dflag)
2567
            gen_op_addl_A0_im(-2);
2568
        else
2569
            gen_op_addl_A0_im(-4);
2570
        if (s->ss32) {
2571
            if (s->addseg) {
2572
                tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2573
                gen_op_addl_A0_seg(s, R_SS);
2574
            }
2575
        } else {
2576
            gen_op_andl_A0_ffff();
2577
            tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2578
            gen_op_addl_A0_seg(s, R_SS);
2579
        }
2580
        gen_op_st_T0_A0(s->dflag + 1 + s->mem_index);
2581
        if (s->ss32 && !s->addseg)
2582
            gen_op_mov_reg_A0(1, R_ESP);
2583
        else
2584
            gen_op_mov_reg_T1(s->ss32 + 1, R_ESP);
2585
    }
2586
}
2587

    
2588
/* generate a push. It depends on ss32, addseg and dflag */
2589
/* slower version for T1, only used for call Ev */
2590
static void gen_push_T1(DisasContext *s)
2591
{
2592
#ifdef TARGET_X86_64
2593
    if (CODE64(s)) {
2594
        gen_op_movq_A0_reg(R_ESP);
2595
        if (s->dflag) {
2596
            gen_op_addq_A0_im(-8);
2597
            gen_op_st_T1_A0(OT_QUAD + s->mem_index);
2598
        } else {
2599
            gen_op_addq_A0_im(-2);
2600
            gen_op_st_T0_A0(OT_WORD + s->mem_index);
2601
        }
2602
        gen_op_mov_reg_A0(2, R_ESP);
2603
    } else
2604
#endif
2605
    {
2606
        gen_op_movl_A0_reg(R_ESP);
2607
        if (!s->dflag)
2608
            gen_op_addl_A0_im(-2);
2609
        else
2610
            gen_op_addl_A0_im(-4);
2611
        if (s->ss32) {
2612
            if (s->addseg) {
2613
                gen_op_addl_A0_seg(s, R_SS);
2614
            }
2615
        } else {
2616
            gen_op_andl_A0_ffff();
2617
            gen_op_addl_A0_seg(s, R_SS);
2618
        }
2619
        gen_op_st_T1_A0(s->dflag + 1 + s->mem_index);
2620

    
2621
        if (s->ss32 && !s->addseg)
2622
            gen_op_mov_reg_A0(1, R_ESP);
2623
        else
2624
            gen_stack_update(s, (-2) << s->dflag);
2625
    }
2626
}
2627

    
2628
/* two step pop is necessary for precise exceptions */
2629
static void gen_pop_T0(DisasContext *s)
2630
{
2631
#ifdef TARGET_X86_64
2632
    if (CODE64(s)) {
2633
        gen_op_movq_A0_reg(R_ESP);
2634
        gen_op_ld_T0_A0((s->dflag ? OT_QUAD : OT_WORD) + s->mem_index);
2635
    } else
2636
#endif
2637
    {
2638
        gen_op_movl_A0_reg(R_ESP);
2639
        if (s->ss32) {
2640
            if (s->addseg)
2641
                gen_op_addl_A0_seg(s, R_SS);
2642
        } else {
2643
            gen_op_andl_A0_ffff();
2644
            gen_op_addl_A0_seg(s, R_SS);
2645
        }
2646
        gen_op_ld_T0_A0(s->dflag + 1 + s->mem_index);
2647
    }
2648
}
2649

    
2650
static void gen_pop_update(DisasContext *s)
2651
{
2652
#ifdef TARGET_X86_64
2653
    if (CODE64(s) && s->dflag) {
2654
        gen_stack_update(s, 8);
2655
    } else
2656
#endif
2657
    {
2658
        gen_stack_update(s, 2 << s->dflag);
2659
    }
2660
}
2661

    
2662
static void gen_stack_A0(DisasContext *s)
2663
{
2664
    gen_op_movl_A0_reg(R_ESP);
2665
    if (!s->ss32)
2666
        gen_op_andl_A0_ffff();
2667
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2668
    if (s->addseg)
2669
        gen_op_addl_A0_seg(s, R_SS);
2670
}
2671

    
2672
/* NOTE: wrap around in 16 bit not fully handled */
2673
static void gen_pusha(DisasContext *s)
2674
{
2675
    int i;
2676
    gen_op_movl_A0_reg(R_ESP);
2677
    gen_op_addl_A0_im(-16 <<  s->dflag);
2678
    if (!s->ss32)
2679
        gen_op_andl_A0_ffff();
2680
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2681
    if (s->addseg)
2682
        gen_op_addl_A0_seg(s, R_SS);
2683
    for(i = 0;i < 8; i++) {
2684
        gen_op_mov_TN_reg(OT_LONG, 0, 7 - i);
2685
        gen_op_st_T0_A0(OT_WORD + s->dflag + s->mem_index);
2686
        gen_op_addl_A0_im(2 <<  s->dflag);
2687
    }
2688
    gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2689
}
2690

    
2691
/* NOTE: wrap around in 16 bit not fully handled */
2692
static void gen_popa(DisasContext *s)
2693
{
2694
    int i;
2695
    gen_op_movl_A0_reg(R_ESP);
2696
    if (!s->ss32)
2697
        gen_op_andl_A0_ffff();
2698
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2699
    tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 16 <<  s->dflag);
2700
    if (s->addseg)
2701
        gen_op_addl_A0_seg(s, R_SS);
2702
    for(i = 0;i < 8; i++) {
2703
        /* ESP is not reloaded */
2704
        if (i != 3) {
2705
            gen_op_ld_T0_A0(OT_WORD + s->dflag + s->mem_index);
2706
            gen_op_mov_reg_T0(OT_WORD + s->dflag, 7 - i);
2707
        }
2708
        gen_op_addl_A0_im(2 <<  s->dflag);
2709
    }
2710
    gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2711
}
2712

    
2713
static void gen_enter(DisasContext *s, int esp_addend, int level)
2714
{
2715
    int ot, opsize;
2716

    
2717
    level &= 0x1f;
2718
#ifdef TARGET_X86_64
2719
    if (CODE64(s)) {
2720
        ot = s->dflag ? OT_QUAD : OT_WORD;
2721
        opsize = 1 << ot;
2722

    
2723
        gen_op_movl_A0_reg(R_ESP);
2724
        gen_op_addq_A0_im(-opsize);
2725
        tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2726

    
2727
        /* push bp */
2728
        gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
2729
        gen_op_st_T0_A0(ot + s->mem_index);
2730
        if (level) {
2731
            /* XXX: must save state */
2732
            gen_helper_enter64_level(cpu_env, tcg_const_i32(level),
2733
                                     tcg_const_i32((ot == OT_QUAD)),
2734
                                     cpu_T[1]);
2735
        }
2736
        gen_op_mov_reg_T1(ot, R_EBP);
2737
        tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2738
        gen_op_mov_reg_T1(OT_QUAD, R_ESP);
2739
    } else
2740
#endif
2741
    {
2742
        ot = s->dflag + OT_WORD;
2743
        opsize = 2 << s->dflag;
2744

    
2745
        gen_op_movl_A0_reg(R_ESP);
2746
        gen_op_addl_A0_im(-opsize);
2747
        if (!s->ss32)
2748
            gen_op_andl_A0_ffff();
2749
        tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2750
        if (s->addseg)
2751
            gen_op_addl_A0_seg(s, R_SS);
2752
        /* push bp */
2753
        gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
2754
        gen_op_st_T0_A0(ot + s->mem_index);
2755
        if (level) {
2756
            /* XXX: must save state */
2757
            gen_helper_enter_level(cpu_env, tcg_const_i32(level),
2758
                                   tcg_const_i32(s->dflag),
2759
                                   cpu_T[1]);
2760
        }
2761
        gen_op_mov_reg_T1(ot, R_EBP);
2762
        tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2763
        gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2764
    }
2765
}
2766

    
2767
static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2768
{
2769
    gen_update_cc_op(s);
2770
    gen_jmp_im(cur_eip);
2771
    gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
2772
    s->is_jmp = DISAS_TB_JUMP;
2773
}
2774

    
2775
/* an interrupt is different from an exception because of the
2776
   privilege checks */
2777
static void gen_interrupt(DisasContext *s, int intno,
2778
                          target_ulong cur_eip, target_ulong next_eip)
2779
{
2780
    gen_update_cc_op(s);
2781
    gen_jmp_im(cur_eip);
2782
    gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
2783
                               tcg_const_i32(next_eip - cur_eip));
2784
    s->is_jmp = DISAS_TB_JUMP;
2785
}
2786

    
2787
static void gen_debug(DisasContext *s, target_ulong cur_eip)
2788
{
2789
    gen_update_cc_op(s);
2790
    gen_jmp_im(cur_eip);
2791
    gen_helper_debug(cpu_env);
2792
    s->is_jmp = DISAS_TB_JUMP;
2793
}
2794

    
2795
/* generate a generic end of block. Trace exception is also generated
2796
   if needed */
2797
static void gen_eob(DisasContext *s)
2798
{
2799
    gen_update_cc_op(s);
2800
    if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
2801
        gen_helper_reset_inhibit_irq(cpu_env);
2802
    }
2803
    if (s->tb->flags & HF_RF_MASK) {
2804
        gen_helper_reset_rf(cpu_env);
2805
    }
2806
    if (s->singlestep_enabled) {
2807
        gen_helper_debug(cpu_env);
2808
    } else if (s->tf) {
2809
        gen_helper_single_step(cpu_env);
2810
    } else {
2811
        tcg_gen_exit_tb(0);
2812
    }
2813
    s->is_jmp = DISAS_TB_JUMP;
2814
}
2815

    
2816
/* generate a jump to eip. No segment change must happen before as a
2817
   direct call to the next block may occur */
2818
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2819
{
2820
    gen_update_cc_op(s);
2821
    set_cc_op(s, CC_OP_DYNAMIC);
2822
    if (s->jmp_opt) {
2823
        gen_goto_tb(s, tb_num, eip);
2824
        s->is_jmp = DISAS_TB_JUMP;
2825
    } else {
2826
        gen_jmp_im(eip);
2827
        gen_eob(s);
2828
    }
2829
}
2830

    
2831
static void gen_jmp(DisasContext *s, target_ulong eip)
2832
{
2833
    gen_jmp_tb(s, eip, 0);
2834
}
2835

    
2836
static inline void gen_ldq_env_A0(int idx, int offset)
2837
{
2838
    int mem_index = (idx >> 2) - 1;
2839
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2840
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
2841
}
2842

    
2843
static inline void gen_stq_env_A0(int idx, int offset)
2844
{
2845
    int mem_index = (idx >> 2) - 1;
2846
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
2847
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2848
}
2849

    
2850
static inline void gen_ldo_env_A0(int idx, int offset)
2851
{
2852
    int mem_index = (idx >> 2) - 1;
2853
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2854
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2855
    tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2856
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2857
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2858
}
2859

    
2860
static inline void gen_sto_env_A0(int idx, int offset)
2861
{
2862
    int mem_index = (idx >> 2) - 1;
2863
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2864
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2865
    tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2866
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2867
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2868
}
2869

    
2870
static inline void gen_op_movo(int d_offset, int s_offset)
2871
{
2872
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2873
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2874
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + 8);
2875
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + 8);
2876
}
2877

    
2878
static inline void gen_op_movq(int d_offset, int s_offset)
2879
{
2880
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2881
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2882
}
2883

    
2884
static inline void gen_op_movl(int d_offset, int s_offset)
2885
{
2886
    tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
2887
    tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
2888
}
2889

    
2890
static inline void gen_op_movq_env_0(int d_offset)
2891
{
2892
    tcg_gen_movi_i64(cpu_tmp1_i64, 0);
2893
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2894
}
2895

    
2896
typedef void (*SSEFunc_i_ep)(TCGv_i32 val, TCGv_ptr env, TCGv_ptr reg);
2897
typedef void (*SSEFunc_l_ep)(TCGv_i64 val, TCGv_ptr env, TCGv_ptr reg);
2898
typedef void (*SSEFunc_0_epi)(TCGv_ptr env, TCGv_ptr reg, TCGv_i32 val);
2899
typedef void (*SSEFunc_0_epl)(TCGv_ptr env, TCGv_ptr reg, TCGv_i64 val);
2900
typedef void (*SSEFunc_0_epp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b);
2901
typedef void (*SSEFunc_0_eppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2902
                               TCGv_i32 val);
2903
typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val);
2904
typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2905
                               TCGv val);
2906

    
2907
#define SSE_SPECIAL ((void *)1)
2908
#define SSE_DUMMY ((void *)2)
2909

    
2910
#define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2911
#define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2912
                     gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2913

    
2914
static const SSEFunc_0_epp sse_op_table1[256][4] = {
2915
    /* 3DNow! extensions */
2916
    [0x0e] = { SSE_DUMMY }, /* femms */
2917
    [0x0f] = { SSE_DUMMY }, /* pf... */
2918
    /* pure SSE operations */
2919
    [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2920
    [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2921
    [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2922
    [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
2923
    [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
2924
    [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
2925
    [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */
2926
    [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */
2927

    
2928
    [0x28] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2929
    [0x29] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2930
    [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2931
    [0x2b] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd, movntss, movntsd */
2932
    [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2933
    [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2934
    [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd },
2935
    [0x2f] = { gen_helper_comiss, gen_helper_comisd },
2936
    [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2937
    [0x51] = SSE_FOP(sqrt),
2938
    [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL },
2939
    [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL },
2940
    [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */
2941
    [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */
2942
    [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */
2943
    [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */
2944
    [0x58] = SSE_FOP(add),
2945
    [0x59] = SSE_FOP(mul),
2946
    [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps,
2947
               gen_helper_cvtss2sd, gen_helper_cvtsd2ss },
2948
    [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq },
2949
    [0x5c] = SSE_FOP(sub),
2950
    [0x5d] = SSE_FOP(min),
2951
    [0x5e] = SSE_FOP(div),
2952
    [0x5f] = SSE_FOP(max),
2953

    
2954
    [0xc2] = SSE_FOP(cmpeq),
2955
    [0xc6] = { (SSEFunc_0_epp)gen_helper_shufps,
2956
               (SSEFunc_0_epp)gen_helper_shufpd }, /* XXX: casts */
2957

    
2958
    [0x38] = { SSE_SPECIAL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* SSSE3/SSE4 */
2959
    [0x3a] = { SSE_SPECIAL, SSE_SPECIAL }, /* SSSE3/SSE4 */
2960

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

    
3047
static const SSEFunc_0_epp sse_op_table2[3 * 8][2] = {
3048
    [0 + 2] = MMX_OP2(psrlw),
3049
    [0 + 4] = MMX_OP2(psraw),
3050
    [0 + 6] = MMX_OP2(psllw),
3051
    [8 + 2] = MMX_OP2(psrld),
3052
    [8 + 4] = MMX_OP2(psrad),
3053
    [8 + 6] = MMX_OP2(pslld),
3054
    [16 + 2] = MMX_OP2(psrlq),
3055
    [16 + 3] = { NULL, gen_helper_psrldq_xmm },
3056
    [16 + 6] = MMX_OP2(psllq),
3057
    [16 + 7] = { NULL, gen_helper_pslldq_xmm },
3058
};
3059

    
3060
static const SSEFunc_0_epi sse_op_table3ai[] = {
3061
    gen_helper_cvtsi2ss,
3062
    gen_helper_cvtsi2sd
3063
};
3064

    
3065
#ifdef TARGET_X86_64
3066
static const SSEFunc_0_epl sse_op_table3aq[] = {
3067
    gen_helper_cvtsq2ss,
3068
    gen_helper_cvtsq2sd
3069
};
3070
#endif
3071

    
3072
static const SSEFunc_i_ep sse_op_table3bi[] = {
3073
    gen_helper_cvttss2si,
3074
    gen_helper_cvtss2si,
3075
    gen_helper_cvttsd2si,
3076
    gen_helper_cvtsd2si
3077
};
3078

    
3079
#ifdef TARGET_X86_64
3080
static const SSEFunc_l_ep sse_op_table3bq[] = {
3081
    gen_helper_cvttss2sq,
3082
    gen_helper_cvtss2sq,
3083
    gen_helper_cvttsd2sq,
3084
    gen_helper_cvtsd2sq
3085
};
3086
#endif
3087

    
3088
static const SSEFunc_0_epp sse_op_table4[8][4] = {
3089
    SSE_FOP(cmpeq),
3090
    SSE_FOP(cmplt),
3091
    SSE_FOP(cmple),
3092
    SSE_FOP(cmpunord),
3093
    SSE_FOP(cmpneq),
3094
    SSE_FOP(cmpnlt),
3095
    SSE_FOP(cmpnle),
3096
    SSE_FOP(cmpord),
3097
};
3098

    
3099
static const SSEFunc_0_epp sse_op_table5[256] = {
3100
    [0x0c] = gen_helper_pi2fw,
3101
    [0x0d] = gen_helper_pi2fd,
3102
    [0x1c] = gen_helper_pf2iw,
3103
    [0x1d] = gen_helper_pf2id,
3104
    [0x8a] = gen_helper_pfnacc,
3105
    [0x8e] = gen_helper_pfpnacc,
3106
    [0x90] = gen_helper_pfcmpge,
3107
    [0x94] = gen_helper_pfmin,
3108
    [0x96] = gen_helper_pfrcp,
3109
    [0x97] = gen_helper_pfrsqrt,
3110
    [0x9a] = gen_helper_pfsub,
3111
    [0x9e] = gen_helper_pfadd,
3112
    [0xa0] = gen_helper_pfcmpgt,
3113
    [0xa4] = gen_helper_pfmax,
3114
    [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
3115
    [0xa7] = gen_helper_movq, /* pfrsqit1 */
3116
    [0xaa] = gen_helper_pfsubr,
3117
    [0xae] = gen_helper_pfacc,
3118
    [0xb0] = gen_helper_pfcmpeq,
3119
    [0xb4] = gen_helper_pfmul,
3120
    [0xb6] = gen_helper_movq, /* pfrcpit2 */
3121
    [0xb7] = gen_helper_pmulhrw_mmx,
3122
    [0xbb] = gen_helper_pswapd,
3123
    [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
3124
};
3125

    
3126
struct SSEOpHelper_epp {
3127
    SSEFunc_0_epp op[2];
3128
    uint32_t ext_mask;
3129
};
3130

    
3131
struct SSEOpHelper_eppi {
3132
    SSEFunc_0_eppi op[2];
3133
    uint32_t ext_mask;
3134
};
3135

    
3136
#define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
3137
#define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
3138
#define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
3139
#define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
3140

    
3141
static const struct SSEOpHelper_epp sse_op_table6[256] = {
3142
    [0x00] = SSSE3_OP(pshufb),
3143
    [0x01] = SSSE3_OP(phaddw),
3144
    [0x02] = SSSE3_OP(phaddd),
3145
    [0x03] = SSSE3_OP(phaddsw),
3146
    [0x04] = SSSE3_OP(pmaddubsw),
3147
    [0x05] = SSSE3_OP(phsubw),
3148
    [0x06] = SSSE3_OP(phsubd),
3149
    [0x07] = SSSE3_OP(phsubsw),
3150
    [0x08] = SSSE3_OP(psignb),
3151
    [0x09] = SSSE3_OP(psignw),
3152
    [0x0a] = SSSE3_OP(psignd),
3153
    [0x0b] = SSSE3_OP(pmulhrsw),
3154
    [0x10] = SSE41_OP(pblendvb),
3155
    [0x14] = SSE41_OP(blendvps),
3156
    [0x15] = SSE41_OP(blendvpd),
3157
    [0x17] = SSE41_OP(ptest),
3158
    [0x1c] = SSSE3_OP(pabsb),
3159
    [0x1d] = SSSE3_OP(pabsw),
3160
    [0x1e] = SSSE3_OP(pabsd),
3161
    [0x20] = SSE41_OP(pmovsxbw),
3162
    [0x21] = SSE41_OP(pmovsxbd),
3163
    [0x22] = SSE41_OP(pmovsxbq),
3164
    [0x23] = SSE41_OP(pmovsxwd),
3165
    [0x24] = SSE41_OP(pmovsxwq),
3166
    [0x25] = SSE41_OP(pmovsxdq),
3167
    [0x28] = SSE41_OP(pmuldq),
3168
    [0x29] = SSE41_OP(pcmpeqq),
3169
    [0x2a] = SSE41_SPECIAL, /* movntqda */
3170
    [0x2b] = SSE41_OP(packusdw),
3171
    [0x30] = SSE41_OP(pmovzxbw),
3172
    [0x31] = SSE41_OP(pmovzxbd),
3173
    [0x32] = SSE41_OP(pmovzxbq),
3174
    [0x33] = SSE41_OP(pmovzxwd),
3175
    [0x34] = SSE41_OP(pmovzxwq),
3176
    [0x35] = SSE41_OP(pmovzxdq),
3177
    [0x37] = SSE42_OP(pcmpgtq),
3178
    [0x38] = SSE41_OP(pminsb),
3179
    [0x39] = SSE41_OP(pminsd),
3180
    [0x3a] = SSE41_OP(pminuw),
3181
    [0x3b] = SSE41_OP(pminud),
3182
    [0x3c] = SSE41_OP(pmaxsb),
3183
    [0x3d] = SSE41_OP(pmaxsd),
3184
    [0x3e] = SSE41_OP(pmaxuw),
3185
    [0x3f] = SSE41_OP(pmaxud),
3186
    [0x40] = SSE41_OP(pmulld),
3187
    [0x41] = SSE41_OP(phminposuw),
3188
};
3189

    
3190
static const struct SSEOpHelper_eppi sse_op_table7[256] = {
3191
    [0x08] = SSE41_OP(roundps),
3192
    [0x09] = SSE41_OP(roundpd),
3193
    [0x0a] = SSE41_OP(roundss),
3194
    [0x0b] = SSE41_OP(roundsd),
3195
    [0x0c] = SSE41_OP(blendps),
3196
    [0x0d] = SSE41_OP(blendpd),
3197
    [0x0e] = SSE41_OP(pblendw),
3198
    [0x0f] = SSSE3_OP(palignr),
3199
    [0x14] = SSE41_SPECIAL, /* pextrb */
3200
    [0x15] = SSE41_SPECIAL, /* pextrw */
3201
    [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */
3202
    [0x17] = SSE41_SPECIAL, /* extractps */
3203
    [0x20] = SSE41_SPECIAL, /* pinsrb */
3204
    [0x21] = SSE41_SPECIAL, /* insertps */
3205
    [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */
3206
    [0x40] = SSE41_OP(dpps),
3207
    [0x41] = SSE41_OP(dppd),
3208
    [0x42] = SSE41_OP(mpsadbw),
3209
    [0x60] = SSE42_OP(pcmpestrm),
3210
    [0x61] = SSE42_OP(pcmpestri),
3211
    [0x62] = SSE42_OP(pcmpistrm),
3212
    [0x63] = SSE42_OP(pcmpistri),
3213
};
3214

    
3215
static void gen_sse(CPUX86State *env, DisasContext *s, int b,
3216
                    target_ulong pc_start, int rex_r)
3217
{
3218
    int b1, op1_offset, op2_offset, is_xmm, val, ot;
3219
    int modrm, mod, rm, reg, reg_addr, offset_addr;
3220
    SSEFunc_0_epp sse_fn_epp;
3221
    SSEFunc_0_eppi sse_fn_eppi;
3222
    SSEFunc_0_ppi sse_fn_ppi;
3223
    SSEFunc_0_eppt sse_fn_eppt;
3224

    
3225
    b &= 0xff;
3226
    if (s->prefix & PREFIX_DATA)
3227
        b1 = 1;
3228
    else if (s->prefix & PREFIX_REPZ)
3229
        b1 = 2;
3230
    else if (s->prefix & PREFIX_REPNZ)
3231
        b1 = 3;
3232
    else
3233
        b1 = 0;
3234
    sse_fn_epp = sse_op_table1[b][b1];
3235
    if (!sse_fn_epp) {
3236
        goto illegal_op;
3237
    }
3238
    if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
3239
        is_xmm = 1;
3240
    } else {
3241
        if (b1 == 0) {
3242
            /* MMX case */
3243
            is_xmm = 0;
3244
        } else {
3245
            is_xmm = 1;
3246
        }
3247
    }
3248
    /* simple MMX/SSE operation */
3249
    if (s->flags & HF_TS_MASK) {
3250
        gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
3251
        return;
3252
    }
3253
    if (s->flags & HF_EM_MASK) {
3254
    illegal_op:
3255
        gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
3256
        return;
3257
    }
3258
    if (is_xmm && !(s->flags & HF_OSFXSR_MASK))
3259
        if ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))
3260
            goto illegal_op;
3261
    if (b == 0x0e) {
3262
        if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
3263
            goto illegal_op;
3264
        /* femms */
3265
        gen_helper_emms(cpu_env);
3266
        return;
3267
    }
3268
    if (b == 0x77) {
3269
        /* emms */
3270
        gen_helper_emms(cpu_env);
3271
        return;
3272
    }
3273
    /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3274
       the static cpu state) */
3275
    if (!is_xmm) {
3276
        gen_helper_enter_mmx(cpu_env);
3277
    }
3278

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

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

    
3853
            sse_fn_epp = sse_op_table6[b].op[b1];
3854
            if (!sse_fn_epp) {
3855
                goto illegal_op;
3856
            }
3857
            if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
3858
                goto illegal_op;
3859

    
3860
            if (b1) {
3861
                op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3862
                if (mod == 3) {
3863
                    op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
3864
                } else {
3865
                    op2_offset = offsetof(CPUX86State,xmm_t0);
3866
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3867
                    switch (b) {
3868
                    case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3869
                    case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3870
                    case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3871
                        gen_ldq_env_A0(s->mem_index, op2_offset +
3872
                                        offsetof(XMMReg, XMM_Q(0)));
3873
                        break;
3874
                    case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3875
                    case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3876
                        tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
3877
                                          (s->mem_index >> 2) - 1);
3878
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
3879
                        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset +
3880
                                        offsetof(XMMReg, XMM_L(0)));
3881
                        break;
3882
                    case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3883
                        tcg_gen_qemu_ld16u(cpu_tmp0, cpu_A0,
3884
                                          (s->mem_index >> 2) - 1);
3885
                        tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset +
3886
                                        offsetof(XMMReg, XMM_W(0)));
3887
                        break;
3888
                    case 0x2a:            /* movntqda */
3889
                        gen_ldo_env_A0(s->mem_index, op1_offset);
3890
                        return;
3891
                    default:
3892
                        gen_ldo_env_A0(s->mem_index, op2_offset);
3893
                    }
3894
                }
3895
            } else {
3896
                op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3897
                if (mod == 3) {
3898
                    op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3899
                } else {
3900
                    op2_offset = offsetof(CPUX86State,mmx_t0);
3901
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3902
                    gen_ldq_env_A0(s->mem_index, op2_offset);
3903
                }
3904
            }
3905
            if (sse_fn_epp == SSE_SPECIAL) {
3906
                goto illegal_op;
3907
            }
3908

    
3909
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3910
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3911
            sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3912

    
3913
            if (b == 0x17) {
3914
                set_cc_op(s, CC_OP_EFLAGS);
3915
            }
3916
            break;
3917
        case 0x338: /* crc32 */
3918
        crc32:
3919
            b = modrm;
3920
            modrm = cpu_ldub_code(env, s->pc++);
3921
            reg = ((modrm >> 3) & 7) | rex_r;
3922

    
3923
            if (b != 0xf0 && b != 0xf1)
3924
                goto illegal_op;
3925
            if (!(s->cpuid_ext_features & CPUID_EXT_SSE42))
3926
                goto illegal_op;
3927

    
3928
            if (b == 0xf0)
3929
                ot = OT_BYTE;
3930
            else if (b == 0xf1 && s->dflag != 2)
3931
                if (s->prefix & PREFIX_DATA)
3932
                    ot = OT_WORD;
3933
                else
3934
                    ot = OT_LONG;
3935
            else
3936
                ot = OT_QUAD;
3937

    
3938
            gen_op_mov_TN_reg(OT_LONG, 0, reg);
3939
            tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3940
            gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3941
            gen_helper_crc32(cpu_T[0], cpu_tmp2_i32,
3942
                             cpu_T[0], tcg_const_i32(8 << ot));
3943

    
3944
            ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3945
            gen_op_mov_reg_T0(ot, reg);
3946
            break;
3947
        case 0x03a:
3948
        case 0x13a:
3949
            b = modrm;
3950
            modrm = cpu_ldub_code(env, s->pc++);
3951
            rm = modrm & 7;
3952
            reg = ((modrm >> 3) & 7) | rex_r;
3953
            mod = (modrm >> 6) & 3;
3954
            if (b1 >= 2) {
3955
                goto illegal_op;
3956
            }
3957

    
3958
            sse_fn_eppi = sse_op_table7[b].op[b1];
3959
            if (!sse_fn_eppi) {
3960
                goto illegal_op;
3961
            }
3962
            if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
3963
                goto illegal_op;
3964

    
3965
            if (sse_fn_eppi == SSE_SPECIAL) {
3966
                ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3967
                rm = (modrm & 7) | REX_B(s);
3968
                if (mod != 3)
3969
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3970
                reg = ((modrm >> 3) & 7) | rex_r;
3971
                val = cpu_ldub_code(env, s->pc++);
3972
                switch (b) {
3973
                case 0x14: /* pextrb */
3974
                    tcg_gen_ld8u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
3975
                                            xmm_regs[reg].XMM_B(val & 15)));
3976
                    if (mod == 3)
3977
                        gen_op_mov_reg_T0(ot, rm);
3978
                    else
3979
                        tcg_gen_qemu_st8(cpu_T[0], cpu_A0,
3980
                                        (s->mem_index >> 2) - 1);
3981
                    break;
3982
                case 0x15: /* pextrw */
3983
                    tcg_gen_ld16u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
3984
                                            xmm_regs[reg].XMM_W(val & 7)));
3985
                    if (mod == 3)
3986
                        gen_op_mov_reg_T0(ot, rm);
3987
                    else
3988
                        tcg_gen_qemu_st16(cpu_T[0], cpu_A0,
3989
                                        (s->mem_index >> 2) - 1);
3990
                    break;
3991
                case 0x16:
3992
                    if (ot == OT_LONG) { /* pextrd */
3993
                        tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
3994
                                        offsetof(CPUX86State,
3995
                                                xmm_regs[reg].XMM_L(val & 3)));
3996
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3997
                        if (mod == 3)
3998
                            gen_op_mov_reg_v(ot, rm, cpu_T[0]);
3999
                        else
4000
                            tcg_gen_qemu_st32(cpu_T[0], cpu_A0,
4001
                                            (s->mem_index >> 2) - 1);
4002
                    } else { /* pextrq */
4003
#ifdef TARGET_X86_64
4004
                        tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
4005
                                        offsetof(CPUX86State,
4006
                                                xmm_regs[reg].XMM_Q(val & 1)));
4007
                        if (mod == 3)
4008
                            gen_op_mov_reg_v(ot, rm, cpu_tmp1_i64);
4009
                        else
4010
                            tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0,
4011
                                            (s->mem_index >> 2) - 1);
4012
#else
4013
                        goto illegal_op;
4014
#endif
4015
                    }
4016
                    break;
4017
                case 0x17: /* extractps */
4018
                    tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
4019
                                            xmm_regs[reg].XMM_L(val & 3)));
4020
                    if (mod == 3)
4021
                        gen_op_mov_reg_T0(ot, rm);
4022
                    else
4023
                        tcg_gen_qemu_st32(cpu_T[0], cpu_A0,
4024
                                        (s->mem_index >> 2) - 1);
4025
                    break;
4026
                case 0x20: /* pinsrb */
4027
                    if (mod == 3)
4028
                        gen_op_mov_TN_reg(OT_LONG, 0, rm);
4029
                    else
4030
                        tcg_gen_qemu_ld8u(cpu_tmp0, cpu_A0,
4031
                                        (s->mem_index >> 2) - 1);
4032
                    tcg_gen_st8_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State,
4033
                                            xmm_regs[reg].XMM_B(val & 15)));
4034
                    break;
4035
                case 0x21: /* insertps */
4036
                    if (mod == 3) {
4037
                        tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4038
                                        offsetof(CPUX86State,xmm_regs[rm]
4039
                                                .XMM_L((val >> 6) & 3)));
4040
                    } else {
4041
                        tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
4042
                                        (s->mem_index >> 2) - 1);
4043
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
4044
                    }
4045
                    tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4046
                                    offsetof(CPUX86State,xmm_regs[reg]
4047
                                            .XMM_L((val >> 4) & 3)));
4048
                    if ((val >> 0) & 1)
4049
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4050
                                        cpu_env, offsetof(CPUX86State,
4051
                                                xmm_regs[reg].XMM_L(0)));
4052
                    if ((val >> 1) & 1)
4053
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4054
                                        cpu_env, offsetof(CPUX86State,
4055
                                                xmm_regs[reg].XMM_L(1)));
4056
                    if ((val >> 2) & 1)
4057
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4058
                                        cpu_env, offsetof(CPUX86State,
4059
                                                xmm_regs[reg].XMM_L(2)));
4060
                    if ((val >> 3) & 1)
4061
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4062
                                        cpu_env, offsetof(CPUX86State,
4063
                                                xmm_regs[reg].XMM_L(3)));
4064
                    break;
4065
                case 0x22:
4066
                    if (ot == OT_LONG) { /* pinsrd */
4067
                        if (mod == 3)
4068
                            gen_op_mov_v_reg(ot, cpu_tmp0, rm);
4069
                        else
4070
                            tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
4071
                                            (s->mem_index >> 2) - 1);
4072
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
4073
                        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4074
                                        offsetof(CPUX86State,
4075
                                                xmm_regs[reg].XMM_L(val & 3)));
4076
                    } else { /* pinsrq */
4077
#ifdef TARGET_X86_64
4078
                        if (mod == 3)
4079
                            gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);
4080
                        else
4081
                            tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0,
4082
                                            (s->mem_index >> 2) - 1);
4083
                        tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
4084
                                        offsetof(CPUX86State,
4085
                                                xmm_regs[reg].XMM_Q(val & 1)));
4086
#else
4087
                        goto illegal_op;
4088
#endif
4089
                    }
4090
                    break;
4091
                }
4092
                return;
4093
            }
4094

    
4095
            if (b1) {
4096
                op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4097
                if (mod == 3) {
4098
                    op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
4099
                } else {
4100
                    op2_offset = offsetof(CPUX86State,xmm_t0);
4101
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4102
                    gen_ldo_env_A0(s->mem_index, op2_offset);
4103
                }
4104
            } else {
4105
                op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4106
                if (mod == 3) {
4107
                    op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4108
                } else {
4109
                    op2_offset = offsetof(CPUX86State,mmx_t0);
4110
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4111
                    gen_ldq_env_A0(s->mem_index, op2_offset);
4112
                }
4113
            }
4114
            val = cpu_ldub_code(env, s->pc++);
4115

    
4116
            if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
4117
                set_cc_op(s, CC_OP_EFLAGS);
4118

    
4119
                if (s->dflag == 2)
4120
                    /* The helper must use entire 64-bit gp registers */
4121
                    val |= 1 << 8;
4122
            }
4123

    
4124
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4125
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4126
            sse_fn_eppi(cpu_env, cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4127
            break;
4128
        default:
4129
            goto illegal_op;
4130
        }
4131
    } else {
4132
        /* generic MMX or SSE operation */
4133
        switch(b) {
4134
        case 0x70: /* pshufx insn */
4135
        case 0xc6: /* pshufx insn */
4136
        case 0xc2: /* compare insns */
4137
            s->rip_offset = 1;
4138
            break;
4139
        default:
4140
            break;
4141
        }
4142
        if (is_xmm) {
4143
            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4144
            if (mod != 3) {
4145
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4146
                op2_offset = offsetof(CPUX86State,xmm_t0);
4147
                if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f && b != 0x5b) ||
4148
                                b == 0xc2)) {
4149
                    /* specific case for SSE single instructions */
4150
                    if (b1 == 2) {
4151
                        /* 32 bit access */
4152
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
4153
                        tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
4154
                    } else {
4155
                        /* 64 bit access */
4156
                        gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_D(0)));
4157
                    }
4158
                } else {
4159
                    gen_ldo_env_A0(s->mem_index, op2_offset);
4160
                }
4161
            } else {
4162
                rm = (modrm & 7) | REX_B(s);
4163
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
4164
            }
4165
        } else {
4166
            op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4167
            if (mod != 3) {
4168
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4169
                op2_offset = offsetof(CPUX86State,mmx_t0);
4170
                gen_ldq_env_A0(s->mem_index, op2_offset);
4171
            } else {
4172
                rm = (modrm & 7);
4173
                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4174
            }
4175
        }
4176
        switch(b) {
4177
        case 0x0f: /* 3DNow! data insns */
4178
            if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
4179
                goto illegal_op;
4180
            val = cpu_ldub_code(env, s->pc++);
4181
            sse_fn_epp = sse_op_table5[val];
4182
            if (!sse_fn_epp) {
4183
                goto illegal_op;
4184
            }
4185
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4186
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4187
            sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4188
            break;
4189
        case 0x70: /* pshufx insn */
4190
        case 0xc6: /* pshufx insn */
4191
            val = cpu_ldub_code(env, s->pc++);
4192
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4193
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4194
            /* XXX: introduce a new table? */
4195
            sse_fn_ppi = (SSEFunc_0_ppi)sse_fn_epp;
4196
            sse_fn_ppi(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4197
            break;
4198
        case 0xc2:
4199
            /* compare insns */
4200
            val = cpu_ldub_code(env, s->pc++);
4201
            if (val >= 8)
4202
                goto illegal_op;
4203
            sse_fn_epp = sse_op_table4[val][b1];
4204

    
4205
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4206
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4207
            sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4208
            break;
4209
        case 0xf7:
4210
            /* maskmov : we must prepare A0 */
4211
            if (mod != 3)
4212
                goto illegal_op;
4213
#ifdef TARGET_X86_64
4214
            if (s->aflag == 2) {
4215
                gen_op_movq_A0_reg(R_EDI);
4216
            } else
4217
#endif
4218
            {
4219
                gen_op_movl_A0_reg(R_EDI);
4220
                if (s->aflag == 0)
4221
                    gen_op_andl_A0_ffff();
4222
            }
4223
            gen_add_A0_ds_seg(s);
4224

    
4225
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4226
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4227
            /* XXX: introduce a new table? */
4228
            sse_fn_eppt = (SSEFunc_0_eppt)sse_fn_epp;
4229
            sse_fn_eppt(cpu_env, cpu_ptr0, cpu_ptr1, cpu_A0);
4230
            break;
4231
        default:
4232
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4233
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4234
            sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4235
            break;
4236
        }
4237
        if (b == 0x2e || b == 0x2f) {
4238
            set_cc_op(s, CC_OP_EFLAGS);
4239
        }
4240
    }
4241
}
4242

    
4243
/* convert one instruction. s->is_jmp is set if the translation must
4244
   be stopped. Return the next pc value */
4245
static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
4246
                               target_ulong pc_start)
4247
{
4248
    int b, prefixes, aflag, dflag;
4249
    int shift, ot;
4250
    int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
4251
    target_ulong next_eip, tval;
4252
    int rex_w, rex_r;
4253

    
4254
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
4255
        tcg_gen_debug_insn_start(pc_start);
4256
    }
4257
    s->pc = pc_start;
4258
    prefixes = 0;
4259
    aflag = s->code32;
4260
    dflag = s->code32;
4261
    s->override = -1;
4262
    rex_w = -1;
4263
    rex_r = 0;
4264
#ifdef TARGET_X86_64
4265
    s->rex_x = 0;
4266
    s->rex_b = 0;
4267
    x86_64_hregs = 0;
4268
#endif
4269
    s->rip_offset = 0; /* for relative ip address */
4270
    s->vex_l = 0;
4271
    s->vex_v = 0;
4272
 next_byte:
4273
    b = cpu_ldub_code(env, s->pc);
4274
    s->pc++;
4275
    /* Collect prefixes.  */
4276
    switch (b) {
4277
    case 0xf3:
4278
        prefixes |= PREFIX_REPZ;
4279
        goto next_byte;
4280
    case 0xf2:
4281
        prefixes |= PREFIX_REPNZ;
4282
        goto next_byte;
4283
    case 0xf0:
4284
        prefixes |= PREFIX_LOCK;
4285
        goto next_byte;
4286
    case 0x2e:
4287
        s->override = R_CS;
4288
        goto next_byte;
4289
    case 0x36:
4290
        s->override = R_SS;
4291
        goto next_byte;
4292
    case 0x3e:
4293
        s->override = R_DS;
4294
        goto next_byte;
4295
    case 0x26:
4296
        s->override = R_ES;
4297
        goto next_byte;
4298
    case 0x64:
4299
        s->override = R_FS;
4300
        goto next_byte;
4301
    case 0x65:
4302
        s->override = R_GS;
4303
        goto next_byte;
4304
    case 0x66:
4305
        prefixes |= PREFIX_DATA;
4306
        goto next_byte;
4307
    case 0x67:
4308
        prefixes |= PREFIX_ADR;
4309
        goto next_byte;
4310
#ifdef TARGET_X86_64
4311
    case 0x40 ... 0x4f:
4312
        if (CODE64(s)) {
4313
            /* REX prefix */
4314
            rex_w = (b >> 3) & 1;
4315
            rex_r = (b & 0x4) << 1;
4316
            s->rex_x = (b & 0x2) << 2;
4317
            REX_B(s) = (b & 0x1) << 3;
4318
            x86_64_hregs = 1; /* select uniform byte register addressing */
4319
            goto next_byte;
4320
        }
4321
        break;
4322
#endif
4323
    case 0xc5: /* 2-byte VEX */
4324
    case 0xc4: /* 3-byte VEX */
4325
        /* VEX prefixes cannot be used except in 32-bit mode.
4326
           Otherwise the instruction is LES or LDS.  */
4327
        if (s->code32 && !s->vm86) {
4328
            static const int pp_prefix[4] = {
4329
                0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ
4330
            };
4331
            int vex3, vex2 = cpu_ldub_code(env, s->pc);
4332

    
4333
            if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
4334
                /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4335
                   otherwise the instruction is LES or LDS.  */
4336
                break;
4337
            }
4338
            s->pc++;
4339

    
4340
            /* 4.1.1-4.1.3: No preceeding lock, 66, f2, f3, or rex prefixes. */
4341
            if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ
4342
                            | PREFIX_LOCK | PREFIX_DATA)) {
4343
                goto illegal_op;
4344
            }
4345
#ifdef TARGET_X86_64
4346
            if (x86_64_hregs) {
4347
                goto illegal_op;
4348
            }
4349
#endif
4350
            rex_r = (~vex2 >> 4) & 8;
4351
            if (b == 0xc5) {
4352
                vex3 = vex2;
4353
                b = cpu_ldub_code(env, s->pc++);
4354
            } else {
4355
#ifdef TARGET_X86_64
4356
                s->rex_x = (~vex2 >> 3) & 8;
4357
                s->rex_b = (~vex2 >> 2) & 8;
4358
#endif
4359
                vex3 = cpu_ldub_code(env, s->pc++);
4360
                rex_w = (vex3 >> 7) & 1;
4361
                switch (vex2 & 0x1f) {
4362
                case 0x01: /* Implied 0f leading opcode bytes.  */
4363
                    b = cpu_ldub_code(env, s->pc++) | 0x100;
4364
                    break;
4365
                case 0x02: /* Implied 0f 38 leading opcode bytes.  */
4366
                    b = 0x138;
4367
                    break;
4368
                case 0x03: /* Implied 0f 3a leading opcode bytes.  */
4369
                    b = 0x13a;
4370
                    break;
4371
                default:   /* Reserved for future use.  */
4372
                    goto illegal_op;
4373
                }
4374
            }
4375
            s->vex_v = (~vex3 >> 3) & 0xf;
4376
            s->vex_l = (vex3 >> 2) & 1;
4377
            prefixes |= pp_prefix[vex3 & 3] | PREFIX_VEX;
4378
        }
4379
        break;
4380
    }
4381

    
4382
    /* Post-process prefixes.  */
4383
    if (prefixes & PREFIX_DATA) {
4384
        dflag ^= 1;
4385
    }
4386
    if (prefixes & PREFIX_ADR) {
4387
        aflag ^= 1;
4388
    }
4389
#ifdef TARGET_X86_64
4390
    if (CODE64(s)) {
4391
        if (rex_w == 1) {
4392
            /* 0x66 is ignored if rex.w is set */
4393
            dflag = 2;
4394
        }
4395
        if (!(prefixes & PREFIX_ADR)) {
4396
            aflag = 2;
4397
        }
4398
    }
4399
#endif
4400

    
4401
    s->prefix = prefixes;
4402
    s->aflag = aflag;
4403
    s->dflag = dflag;
4404

    
4405
    /* lock generation */
4406
    if (prefixes & PREFIX_LOCK)
4407
        gen_helper_lock();
4408

    
4409
    /* now check op code */
4410
 reswitch:
4411
    switch(b) {
4412
    case 0x0f:
4413
        /**************************/
4414
        /* extended op code */
4415
        b = cpu_ldub_code(env, s->pc++) | 0x100;
4416
        goto reswitch;
4417

    
4418
        /**************************/
4419
        /* arith & logic */
4420
    case 0x00 ... 0x05:
4421
    case 0x08 ... 0x0d:
4422
    case 0x10 ... 0x15:
4423
    case 0x18 ... 0x1d:
4424
    case 0x20 ... 0x25:
4425
    case 0x28 ... 0x2d:
4426
    case 0x30 ... 0x35:
4427
    case 0x38 ... 0x3d:
4428
        {
4429
            int op, f, val;
4430
            op = (b >> 3) & 7;
4431
            f = (b >> 1) & 3;
4432

    
4433
            if ((b & 1) == 0)
4434
                ot = OT_BYTE;
4435
            else
4436
                ot = dflag + OT_WORD;
4437

    
4438
            switch(f) {
4439
            case 0: /* OP Ev, Gv */
4440
                modrm = cpu_ldub_code(env, s->pc++);
4441
                reg = ((modrm >> 3) & 7) | rex_r;
4442
                mod = (modrm >> 6) & 3;
4443
                rm = (modrm & 7) | REX_B(s);
4444
                if (mod != 3) {
4445
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4446
                    opreg = OR_TMP0;
4447
                } else if (op == OP_XORL && rm == reg) {
4448
                xor_zero:
4449
                    /* xor reg, reg optimisation */
4450
                    gen_op_movl_T0_0();
4451
                    set_cc_op(s, CC_OP_LOGICB + ot);
4452
                    gen_op_mov_reg_T0(ot, reg);
4453
                    gen_op_update1_cc();
4454
                    break;
4455
                } else {
4456
                    opreg = rm;
4457
                }
4458
                gen_op_mov_TN_reg(ot, 1, reg);
4459
                gen_op(s, op, ot, opreg);
4460
                break;
4461
            case 1: /* OP Gv, Ev */
4462
                modrm = cpu_ldub_code(env, s->pc++);
4463
                mod = (modrm >> 6) & 3;
4464
                reg = ((modrm >> 3) & 7) | rex_r;
4465
                rm = (modrm & 7) | REX_B(s);
4466
                if (mod != 3) {
4467
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4468
                    gen_op_ld_T1_A0(ot + s->mem_index);
4469
                } else if (op == OP_XORL && rm == reg) {
4470
                    goto xor_zero;
4471
                } else {
4472
                    gen_op_mov_TN_reg(ot, 1, rm);
4473
                }
4474
                gen_op(s, op, ot, reg);
4475
                break;
4476
            case 2: /* OP A, Iv */
4477
                val = insn_get(env, s, ot);
4478
                gen_op_movl_T1_im(val);
4479
                gen_op(s, op, ot, OR_EAX);
4480
                break;
4481
            }
4482
        }
4483
        break;
4484

    
4485
    case 0x82:
4486
        if (CODE64(s))
4487
            goto illegal_op;
4488
    case 0x80: /* GRP1 */
4489
    case 0x81:
4490
    case 0x83:
4491
        {
4492
            int val;
4493

    
4494
            if ((b & 1) == 0)
4495
                ot = OT_BYTE;
4496
            else
4497
                ot = dflag + OT_WORD;
4498

    
4499
            modrm = cpu_ldub_code(env, s->pc++);
4500
            mod = (modrm >> 6) & 3;
4501
            rm = (modrm & 7) | REX_B(s);
4502
            op = (modrm >> 3) & 7;
4503

    
4504
            if (mod != 3) {
4505
                if (b == 0x83)
4506
                    s->rip_offset = 1;
4507
                else
4508
                    s->rip_offset = insn_const_size(ot);
4509
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4510
                opreg = OR_TMP0;
4511
            } else {
4512
                opreg = rm;
4513
            }
4514

    
4515
            switch(b) {
4516
            default:
4517
            case 0x80:
4518
            case 0x81:
4519
            case 0x82:
4520
                val = insn_get(env, s, ot);
4521
                break;
4522
            case 0x83:
4523
                val = (int8_t)insn_get(env, s, OT_BYTE);
4524
                break;
4525
            }
4526
            gen_op_movl_T1_im(val);
4527
            gen_op(s, op, ot, opreg);
4528
        }
4529
        break;
4530

    
4531
        /**************************/
4532
        /* inc, dec, and other misc arith */
4533
    case 0x40 ... 0x47: /* inc Gv */
4534
        ot = dflag ? OT_LONG : OT_WORD;
4535
        gen_inc(s, ot, OR_EAX + (b & 7), 1);
4536
        break;
4537
    case 0x48 ... 0x4f: /* dec Gv */
4538
        ot = dflag ? OT_LONG : OT_WORD;
4539
        gen_inc(s, ot, OR_EAX + (b & 7), -1);
4540
        break;
4541
    case 0xf6: /* GRP3 */
4542
    case 0xf7:
4543
        if ((b & 1) == 0)
4544
            ot = OT_BYTE;
4545
        else
4546
            ot = dflag + OT_WORD;
4547

    
4548
        modrm = cpu_ldub_code(env, s->pc++);
4549
        mod = (modrm >> 6) & 3;
4550
        rm = (modrm & 7) | REX_B(s);
4551
        op = (modrm >> 3) & 7;
4552
        if (mod != 3) {
4553
            if (op == 0)
4554
                s->rip_offset = insn_const_size(ot);
4555
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4556
            gen_op_ld_T0_A0(ot + s->mem_index);
4557
        } else {
4558
            gen_op_mov_TN_reg(ot, 0, rm);
4559
        }
4560

    
4561
        switch(op) {
4562
        case 0: /* test */
4563
            val = insn_get(env, s, ot);
4564
            gen_op_movl_T1_im(val);
4565
            gen_op_testl_T0_T1_cc();
4566
            set_cc_op(s, CC_OP_LOGICB + ot);
4567
            break;
4568
        case 2: /* not */
4569
            tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
4570
            if (mod != 3) {
4571
                gen_op_st_T0_A0(ot + s->mem_index);
4572
            } else {
4573
                gen_op_mov_reg_T0(ot, rm);
4574
            }
4575
            break;
4576
        case 3: /* neg */
4577
            tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
4578
            if (mod != 3) {
4579
                gen_op_st_T0_A0(ot + s->mem_index);
4580
            } else {
4581
                gen_op_mov_reg_T0(ot, rm);
4582
            }
4583
            gen_op_update_neg_cc();
4584
            set_cc_op(s, CC_OP_SUBB + ot);
4585
            break;
4586
        case 4: /* mul */
4587
            switch(ot) {
4588
            case OT_BYTE:
4589
                gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX);
4590
                tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
4591
                tcg_gen_ext8u_tl(cpu_T[1], cpu_T[1]);
4592
                /* XXX: use 32 bit mul which could be faster */
4593
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4594
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
4595
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4596
                tcg_gen_andi_tl(cpu_cc_src, cpu_T[0], 0xff00);
4597
                set_cc_op(s, CC_OP_MULB);
4598
                break;
4599
            case OT_WORD:
4600
                gen_op_mov_TN_reg(OT_WORD, 1, R_EAX);
4601
                tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
4602
                tcg_gen_ext16u_tl(cpu_T[1], cpu_T[1]);
4603
                /* XXX: use 32 bit mul which could be faster */
4604
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4605
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
4606
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4607
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
4608
                gen_op_mov_reg_T0(OT_WORD, R_EDX);
4609
                tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4610
                set_cc_op(s, CC_OP_MULW);
4611
                break;
4612
            default:
4613
            case OT_LONG:
4614
#ifdef TARGET_X86_64
4615
                gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4616
                tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
4617
                tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
4618
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4619
                gen_op_mov_reg_T0(OT_LONG, R_EAX);
4620
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4621
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
4622
                gen_op_mov_reg_T0(OT_LONG, R_EDX);
4623
                tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4624
#else
4625
                {
4626
                    TCGv_i64 t0, t1;
4627
                    t0 = tcg_temp_new_i64();
4628
                    t1 = tcg_temp_new_i64();
4629
                    gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4630
                    tcg_gen_extu_i32_i64(t0, cpu_T[0]);
4631
                    tcg_gen_extu_i32_i64(t1, cpu_T[1]);
4632
                    tcg_gen_mul_i64(t0, t0, t1);
4633
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4634
                    gen_op_mov_reg_T0(OT_LONG, R_EAX);
4635
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4636
                    tcg_gen_shri_i64(t0, t0, 32);
4637
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4638
                    gen_op_mov_reg_T0(OT_LONG, R_EDX);
4639
                    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4640
                }
4641
#endif
4642
                set_cc_op(s, CC_OP_MULL);
4643
                break;
4644
#ifdef TARGET_X86_64
4645
            case OT_QUAD:
4646
                gen_helper_mulq_EAX_T0(cpu_env, cpu_T[0]);
4647
                set_cc_op(s, CC_OP_MULQ);
4648
                break;
4649
#endif
4650
            }
4651
            break;
4652
        case 5: /* imul */
4653
            switch(ot) {
4654
            case OT_BYTE:
4655
                gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX);
4656
                tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
4657
                tcg_gen_ext8s_tl(cpu_T[1], cpu_T[1]);
4658
                /* XXX: use 32 bit mul which could be faster */
4659
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4660
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
4661
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4662
                tcg_gen_ext8s_tl(cpu_tmp0, cpu_T[0]);
4663
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4664
                set_cc_op(s, CC_OP_MULB);
4665
                break;
4666
            case OT_WORD:
4667
                gen_op_mov_TN_reg(OT_WORD, 1, R_EAX);
4668
                tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4669
                tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
4670
                /* XXX: use 32 bit mul which could be faster */
4671
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4672
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
4673
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4674
                tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
4675
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4676
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
4677
                gen_op_mov_reg_T0(OT_WORD, R_EDX);
4678
                set_cc_op(s, CC_OP_MULW);
4679
                break;
4680
            default:
4681
            case OT_LONG:
4682
#ifdef TARGET_X86_64
4683
                gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4684
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4685
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
4686
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4687
                gen_op_mov_reg_T0(OT_LONG, R_EAX);
4688
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4689
                tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
4690
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4691
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
4692
                gen_op_mov_reg_T0(OT_LONG, R_EDX);
4693
#else
4694
                {
4695
                    TCGv_i64 t0, t1;
4696
                    t0 = tcg_temp_new_i64();
4697
                    t1 = tcg_temp_new_i64();
4698
                    gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4699
                    tcg_gen_ext_i32_i64(t0, cpu_T[0]);
4700
                    tcg_gen_ext_i32_i64(t1, cpu_T[1]);
4701
                    tcg_gen_mul_i64(t0, t0, t1);
4702
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4703
                    gen_op_mov_reg_T0(OT_LONG, R_EAX);
4704
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4705
                    tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
4706
                    tcg_gen_shri_i64(t0, t0, 32);
4707
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4708
                    gen_op_mov_reg_T0(OT_LONG, R_EDX);
4709
                    tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4710
                }
4711
#endif
4712
                set_cc_op(s, CC_OP_MULL);
4713
                break;
4714
#ifdef TARGET_X86_64
4715
            case OT_QUAD:
4716
                gen_helper_imulq_EAX_T0(cpu_env, cpu_T[0]);
4717
                set_cc_op(s, CC_OP_MULQ);
4718
                break;
4719
#endif
4720
            }
4721
            break;
4722
        case 6: /* div */
4723
            switch(ot) {
4724
            case OT_BYTE:
4725
                gen_jmp_im(pc_start - s->cs_base);
4726
                gen_helper_divb_AL(cpu_env, cpu_T[0]);
4727
                break;
4728
            case OT_WORD:
4729
                gen_jmp_im(pc_start - s->cs_base);
4730
                gen_helper_divw_AX(cpu_env, cpu_T[0]);
4731
                break;
4732
            default:
4733
            case OT_LONG:
4734
                gen_jmp_im(pc_start - s->cs_base);
4735
                gen_helper_divl_EAX(cpu_env, cpu_T[0]);
4736
                break;
4737
#ifdef TARGET_X86_64
4738
            case OT_QUAD:
4739
                gen_jmp_im(pc_start - s->cs_base);
4740
                gen_helper_divq_EAX(cpu_env, cpu_T[0]);
4741
                break;
4742
#endif
4743
            }
4744
            break;
4745
        case 7: /* idiv */
4746
            switch(ot) {
4747
            case OT_BYTE:
4748
                gen_jmp_im(pc_start - s->cs_base);
4749
                gen_helper_idivb_AL(cpu_env, cpu_T[0]);
4750
                break;
4751
            case OT_WORD:
4752
                gen_jmp_im(pc_start - s->cs_base);
4753
                gen_helper_idivw_AX(cpu_env, cpu_T[0]);
4754
                break;
4755
            default:
4756
            case OT_LONG:
4757
                gen_jmp_im(pc_start - s->cs_base);
4758
                gen_helper_idivl_EAX(cpu_env, cpu_T[0]);
4759
                break;
4760
#ifdef TARGET_X86_64
4761
            case OT_QUAD:
4762
                gen_jmp_im(pc_start - s->cs_base);
4763
                gen_helper_idivq_EAX(cpu_env, cpu_T[0]);
4764
                break;
4765
#endif
4766
            }
4767
            break;
4768
        default:
4769
            goto illegal_op;
4770
        }
4771
        break;
4772

    
4773
    case 0xfe: /* GRP4 */
4774
    case 0xff: /* GRP5 */
4775
        if ((b & 1) == 0)
4776
            ot = OT_BYTE;
4777
        else
4778
            ot = dflag + OT_WORD;
4779

    
4780
        modrm = cpu_ldub_code(env, s->pc++);
4781
        mod = (modrm >> 6) & 3;
4782
        rm = (modrm & 7) | REX_B(s);
4783
        op = (modrm >> 3) & 7;
4784
        if (op >= 2 && b == 0xfe) {
4785
            goto illegal_op;
4786
        }
4787
        if (CODE64(s)) {
4788
            if (op == 2 || op == 4) {
4789
                /* operand size for jumps is 64 bit */
4790
                ot = OT_QUAD;
4791
            } else if (op == 3 || op == 5) {
4792
                ot = dflag ? OT_LONG + (rex_w == 1) : OT_WORD;
4793
            } else if (op == 6) {
4794
                /* default push size is 64 bit */
4795
                ot = dflag ? OT_QUAD : OT_WORD;
4796
            }
4797
        }
4798
        if (mod != 3) {
4799
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4800
            if (op >= 2 && op != 3 && op != 5)
4801
                gen_op_ld_T0_A0(ot + s->mem_index);
4802
        } else {
4803
            gen_op_mov_TN_reg(ot, 0, rm);
4804
        }
4805

    
4806
        switch(op) {
4807
        case 0: /* inc Ev */
4808
            if (mod != 3)
4809
                opreg = OR_TMP0;
4810
            else
4811
                opreg = rm;
4812
            gen_inc(s, ot, opreg, 1);
4813
            break;
4814
        case 1: /* dec Ev */
4815
            if (mod != 3)
4816
                opreg = OR_TMP0;
4817
            else
4818
                opreg = rm;
4819
            gen_inc(s, ot, opreg, -1);
4820
            break;
4821
        case 2: /* call Ev */
4822
            /* XXX: optimize if memory (no 'and' is necessary) */
4823
            if (s->dflag == 0)
4824
                gen_op_andl_T0_ffff();
4825
            next_eip = s->pc - s->cs_base;
4826
            gen_movtl_T1_im(next_eip);
4827
            gen_push_T1(s);
4828
            gen_op_jmp_T0();
4829
            gen_eob(s);
4830
            break;
4831
        case 3: /* lcall Ev */
4832
            gen_op_ld_T1_A0(ot + s->mem_index);
4833
            gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4834
            gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
4835
        do_lcall:
4836
            if (s->pe && !s->vm86) {
4837
                gen_update_cc_op(s);
4838
                gen_jmp_im(pc_start - s->cs_base);
4839
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4840
                gen_helper_lcall_protected(cpu_env, cpu_tmp2_i32, cpu_T[1],
4841
                                           tcg_const_i32(dflag),
4842
                                           tcg_const_i32(s->pc - pc_start));
4843
            } else {
4844
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4845
                gen_helper_lcall_real(cpu_env, cpu_tmp2_i32, cpu_T[1],
4846
                                      tcg_const_i32(dflag),
4847
                                      tcg_const_i32(s->pc - s->cs_base));
4848
            }
4849
            gen_eob(s);
4850
            break;
4851
        case 4: /* jmp Ev */
4852
            if (s->dflag == 0)
4853
                gen_op_andl_T0_ffff();
4854
            gen_op_jmp_T0();
4855
            gen_eob(s);
4856
            break;
4857
        case 5: /* ljmp Ev */
4858
            gen_op_ld_T1_A0(ot + s->mem_index);
4859
            gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4860
            gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
4861
        do_ljmp:
4862
            if (s->pe && !s->vm86) {
4863
                gen_update_cc_op(s);
4864
                gen_jmp_im(pc_start - s->cs_base);
4865
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4866
                gen_helper_ljmp_protected(cpu_env, cpu_tmp2_i32, cpu_T[1],
4867
                                          tcg_const_i32(s->pc - pc_start));
4868
            } else {
4869
                gen_op_movl_seg_T0_vm(R_CS);
4870
                gen_op_movl_T0_T1();
4871
                gen_op_jmp_T0();
4872
            }
4873
            gen_eob(s);
4874
            break;
4875
        case 6: /* push Ev */
4876
            gen_push_T0(s);
4877
            break;
4878
        default:
4879
            goto illegal_op;
4880
        }
4881
        break;
4882

    
4883
    case 0x84: /* test Ev, Gv */
4884
    case 0x85:
4885
        if ((b & 1) == 0)
4886
            ot = OT_BYTE;
4887
        else
4888
            ot = dflag + OT_WORD;
4889

    
4890
        modrm = cpu_ldub_code(env, s->pc++);
4891
        reg = ((modrm >> 3) & 7) | rex_r;
4892

    
4893
        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4894
        gen_op_mov_TN_reg(ot, 1, reg);
4895
        gen_op_testl_T0_T1_cc();
4896
        set_cc_op(s, CC_OP_LOGICB + ot);
4897
        break;
4898

    
4899
    case 0xa8: /* test eAX, Iv */
4900
    case 0xa9:
4901
        if ((b & 1) == 0)
4902
            ot = OT_BYTE;
4903
        else
4904
            ot = dflag + OT_WORD;
4905
        val = insn_get(env, s, ot);
4906

    
4907
        gen_op_mov_TN_reg(ot, 0, OR_EAX);
4908
        gen_op_movl_T1_im(val);
4909
        gen_op_testl_T0_T1_cc();
4910
        set_cc_op(s, CC_OP_LOGICB + ot);
4911
        break;
4912

    
4913
    case 0x98: /* CWDE/CBW */
4914
#ifdef TARGET_X86_64
4915
        if (dflag == 2) {
4916
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
4917
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4918
            gen_op_mov_reg_T0(OT_QUAD, R_EAX);
4919
        } else
4920
#endif
4921
        if (dflag == 1) {
4922
            gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
4923
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4924
            gen_op_mov_reg_T0(OT_LONG, R_EAX);
4925
        } else {
4926
            gen_op_mov_TN_reg(OT_BYTE, 0, R_EAX);
4927
            tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
4928
            gen_op_mov_reg_T0(OT_WORD, R_EAX);
4929
        }
4930
        break;
4931
    case 0x99: /* CDQ/CWD */
4932
#ifdef TARGET_X86_64
4933
        if (dflag == 2) {
4934
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
4935
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 63);
4936
            gen_op_mov_reg_T0(OT_QUAD, R_EDX);
4937
        } else
4938
#endif
4939
        if (dflag == 1) {
4940
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
4941
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4942
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 31);
4943
            gen_op_mov_reg_T0(OT_LONG, R_EDX);
4944
        } else {
4945
            gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
4946
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4947
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 15);
4948
            gen_op_mov_reg_T0(OT_WORD, R_EDX);
4949
        }
4950
        break;
4951
    case 0x1af: /* imul Gv, Ev */
4952
    case 0x69: /* imul Gv, Ev, I */
4953
    case 0x6b:
4954
        ot = dflag + OT_WORD;
4955
        modrm = cpu_ldub_code(env, s->pc++);
4956
        reg = ((modrm >> 3) & 7) | rex_r;
4957
        if (b == 0x69)
4958
            s->rip_offset = insn_const_size(ot);
4959
        else if (b == 0x6b)
4960
            s->rip_offset = 1;
4961
        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4962
        if (b == 0x69) {
4963
            val = insn_get(env, s, ot);
4964
            gen_op_movl_T1_im(val);
4965
        } else if (b == 0x6b) {
4966
            val = (int8_t)insn_get(env, s, OT_BYTE);
4967
            gen_op_movl_T1_im(val);
4968
        } else {
4969
            gen_op_mov_TN_reg(ot, 1, reg);
4970
        }
4971

    
4972
#ifdef TARGET_X86_64
4973
        if (ot == OT_QUAD) {
4974
            gen_helper_imulq_T0_T1(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
4975
        } else
4976
#endif
4977
        if (ot == OT_LONG) {
4978
#ifdef TARGET_X86_64
4979
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4980
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
4981
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4982
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4983
                tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
4984
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4985
#else
4986
                {
4987
                    TCGv_i64 t0, t1;
4988
                    t0 = tcg_temp_new_i64();
4989
                    t1 = tcg_temp_new_i64();
4990
                    tcg_gen_ext_i32_i64(t0, cpu_T[0]);
4991
                    tcg_gen_ext_i32_i64(t1, cpu_T[1]);
4992
                    tcg_gen_mul_i64(t0, t0, t1);
4993
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4994
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4995
                    tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
4996
                    tcg_gen_shri_i64(t0, t0, 32);
4997
                    tcg_gen_trunc_i64_i32(cpu_T[1], t0);
4998
                    tcg_gen_sub_tl(cpu_cc_src, cpu_T[1], cpu_tmp0);
4999
                }
5000
#endif
5001
        } else {
5002
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
5003
            tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
5004
            /* XXX: use 32 bit mul which could be faster */
5005
            tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
5006
            tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
5007
            tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
5008
            tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
5009
        }
5010
        gen_op_mov_reg_T0(ot, reg);
5011
        set_cc_op(s, CC_OP_MULB + ot);
5012
        break;
5013
    case 0x1c0:
5014
    case 0x1c1: /* xadd Ev, Gv */
5015
        if ((b & 1) == 0)
5016
            ot = OT_BYTE;
5017
        else
5018
            ot = dflag + OT_WORD;
5019
        modrm = cpu_ldub_code(env, s->pc++);
5020
        reg = ((modrm >> 3) & 7) | rex_r;
5021
        mod = (modrm >> 6) & 3;
5022
        if (mod == 3) {
5023
            rm = (modrm & 7) | REX_B(s);
5024
            gen_op_mov_TN_reg(ot, 0, reg);
5025
            gen_op_mov_TN_reg(ot, 1, rm);
5026
            gen_op_addl_T0_T1();
5027
            gen_op_mov_reg_T1(ot, reg);
5028
            gen_op_mov_reg_T0(ot, rm);
5029
        } else {
5030
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5031
            gen_op_mov_TN_reg(ot, 0, reg);
5032
            gen_op_ld_T1_A0(ot + s->mem_index);
5033
            gen_op_addl_T0_T1();
5034
            gen_op_st_T0_A0(ot + s->mem_index);
5035
            gen_op_mov_reg_T1(ot, reg);
5036
        }
5037
        gen_op_update2_cc();
5038
        set_cc_op(s, CC_OP_ADDB + ot);
5039
        break;
5040
    case 0x1b0:
5041
    case 0x1b1: /* cmpxchg Ev, Gv */
5042
        {
5043
            int label1, label2;
5044
            TCGv t0, t1, t2, a0;
5045

    
5046
            if ((b & 1) == 0)
5047
                ot = OT_BYTE;
5048
            else
5049
                ot = dflag + OT_WORD;
5050
            modrm = cpu_ldub_code(env, s->pc++);
5051
            reg = ((modrm >> 3) & 7) | rex_r;
5052
            mod = (modrm >> 6) & 3;
5053
            t0 = tcg_temp_local_new();
5054
            t1 = tcg_temp_local_new();
5055
            t2 = tcg_temp_local_new();
5056
            a0 = tcg_temp_local_new();
5057
            gen_op_mov_v_reg(ot, t1, reg);
5058
            if (mod == 3) {
5059
                rm = (modrm & 7) | REX_B(s);
5060
                gen_op_mov_v_reg(ot, t0, rm);
5061
            } else {
5062
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5063
                tcg_gen_mov_tl(a0, cpu_A0);
5064
                gen_op_ld_v(ot + s->mem_index, t0, a0);
5065
                rm = 0; /* avoid warning */
5066
            }
5067
            label1 = gen_new_label();
5068
            tcg_gen_mov_tl(t2, cpu_regs[R_EAX]);
5069
            gen_extu(ot, t0);
5070
            gen_extu(ot, t2);
5071
            tcg_gen_brcond_tl(TCG_COND_EQ, t2, t0, label1);
5072
            label2 = gen_new_label();
5073
            if (mod == 3) {
5074
                gen_op_mov_reg_v(ot, R_EAX, t0);
5075
                tcg_gen_br(label2);
5076
                gen_set_label(label1);
5077
                gen_op_mov_reg_v(ot, rm, t1);
5078
            } else {
5079
                /* perform no-op store cycle like physical cpu; must be
5080
                   before changing accumulator to ensure idempotency if
5081
                   the store faults and the instruction is restarted */
5082
                gen_op_st_v(ot + s->mem_index, t0, a0);
5083
                gen_op_mov_reg_v(ot, R_EAX, t0);
5084
                tcg_gen_br(label2);
5085
                gen_set_label(label1);
5086
                gen_op_st_v(ot + s->mem_index, t1, a0);
5087
            }
5088
            gen_set_label(label2);
5089
            tcg_gen_mov_tl(cpu_cc_src, t0);
5090
            tcg_gen_mov_tl(cpu_cc_srcT, t2);
5091
            tcg_gen_sub_tl(cpu_cc_dst, t2, t0);
5092
            set_cc_op(s, CC_OP_SUBB + ot);
5093
            tcg_temp_free(t0);
5094
            tcg_temp_free(t1);
5095
            tcg_temp_free(t2);
5096
            tcg_temp_free(a0);
5097
        }
5098
        break;
5099
    case 0x1c7: /* cmpxchg8b */
5100
        modrm = cpu_ldub_code(env, s->pc++);
5101
        mod = (modrm >> 6) & 3;
5102
        if ((mod == 3) || ((modrm & 0x38) != 0x8))
5103
            goto illegal_op;
5104
#ifdef TARGET_X86_64
5105
        if (dflag == 2) {
5106
            if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
5107
                goto illegal_op;
5108
            gen_jmp_im(pc_start - s->cs_base);
5109
            gen_update_cc_op(s);
5110
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5111
            gen_helper_cmpxchg16b(cpu_env, cpu_A0);
5112
        } else
5113
#endif        
5114
        {
5115
            if (!(s->cpuid_features & CPUID_CX8))
5116
                goto illegal_op;
5117
            gen_jmp_im(pc_start - s->cs_base);
5118
            gen_update_cc_op(s);
5119
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5120
            gen_helper_cmpxchg8b(cpu_env, cpu_A0);
5121
        }
5122
        set_cc_op(s, CC_OP_EFLAGS);
5123
        break;
5124

    
5125
        /**************************/
5126
        /* push/pop */
5127
    case 0x50 ... 0x57: /* push */
5128
        gen_op_mov_TN_reg(OT_LONG, 0, (b & 7) | REX_B(s));
5129
        gen_push_T0(s);
5130
        break;
5131
    case 0x58 ... 0x5f: /* pop */
5132
        if (CODE64(s)) {
5133
            ot = dflag ? OT_QUAD : OT_WORD;
5134
        } else {
5135
            ot = dflag + OT_WORD;
5136
        }
5137
        gen_pop_T0(s);
5138
        /* NOTE: order is important for pop %sp */
5139
        gen_pop_update(s);
5140
        gen_op_mov_reg_T0(ot, (b & 7) | REX_B(s));
5141
        break;
5142
    case 0x60: /* pusha */
5143
        if (CODE64(s))
5144
            goto illegal_op;
5145
        gen_pusha(s);
5146
        break;
5147
    case 0x61: /* popa */
5148
        if (CODE64(s))
5149
            goto illegal_op;
5150
        gen_popa(s);
5151
        break;
5152
    case 0x68: /* push Iv */
5153
    case 0x6a:
5154
        if (CODE64(s)) {
5155
            ot = dflag ? OT_QUAD : OT_WORD;
5156
        } else {
5157
            ot = dflag + OT_WORD;
5158
        }
5159
        if (b == 0x68)
5160
            val = insn_get(env, s, ot);
5161
        else
5162
            val = (int8_t)insn_get(env, s, OT_BYTE);
5163
        gen_op_movl_T0_im(val);
5164
        gen_push_T0(s);
5165
        break;
5166
    case 0x8f: /* pop Ev */
5167
        if (CODE64(s)) {
5168
            ot = dflag ? OT_QUAD : OT_WORD;
5169
        } else {
5170
            ot = dflag + OT_WORD;
5171
        }
5172
        modrm = cpu_ldub_code(env, s->pc++);
5173
        mod = (modrm >> 6) & 3;
5174
        gen_pop_T0(s);
5175
        if (mod == 3) {
5176
            /* NOTE: order is important for pop %sp */
5177
            gen_pop_update(s);
5178
            rm = (modrm & 7) | REX_B(s);
5179
            gen_op_mov_reg_T0(ot, rm);
5180
        } else {
5181
            /* NOTE: order is important too for MMU exceptions */
5182
            s->popl_esp_hack = 1 << ot;
5183
            gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5184
            s->popl_esp_hack = 0;
5185
            gen_pop_update(s);
5186
        }
5187
        break;
5188
    case 0xc8: /* enter */
5189
        {
5190
            int level;
5191
            val = cpu_lduw_code(env, s->pc);
5192
            s->pc += 2;
5193
            level = cpu_ldub_code(env, s->pc++);
5194
            gen_enter(s, val, level);
5195
        }
5196
        break;
5197
    case 0xc9: /* leave */
5198
        /* XXX: exception not precise (ESP is updated before potential exception) */
5199
        if (CODE64(s)) {
5200
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EBP);
5201
            gen_op_mov_reg_T0(OT_QUAD, R_ESP);
5202
        } else if (s->ss32) {
5203
            gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
5204
            gen_op_mov_reg_T0(OT_LONG, R_ESP);
5205
        } else {
5206
            gen_op_mov_TN_reg(OT_WORD, 0, R_EBP);
5207
            gen_op_mov_reg_T0(OT_WORD, R_ESP);
5208
        }
5209
        gen_pop_T0(s);
5210
        if (CODE64(s)) {
5211
            ot = dflag ? OT_QUAD : OT_WORD;
5212
        } else {
5213
            ot = dflag + OT_WORD;
5214
        }
5215
        gen_op_mov_reg_T0(ot, R_EBP);
5216
        gen_pop_update(s);
5217
        break;
5218
    case 0x06: /* push es */
5219
    case 0x0e: /* push cs */
5220
    case 0x16: /* push ss */
5221
    case 0x1e: /* push ds */
5222
        if (CODE64(s))
5223
            goto illegal_op;
5224
        gen_op_movl_T0_seg(b >> 3);
5225
        gen_push_T0(s);
5226
        break;
5227
    case 0x1a0: /* push fs */
5228
    case 0x1a8: /* push gs */
5229
        gen_op_movl_T0_seg((b >> 3) & 7);
5230
        gen_push_T0(s);
5231
        break;
5232
    case 0x07: /* pop es */
5233
    case 0x17: /* pop ss */
5234
    case 0x1f: /* pop ds */
5235
        if (CODE64(s))
5236
            goto illegal_op;
5237
        reg = b >> 3;
5238
        gen_pop_T0(s);
5239
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
5240
        gen_pop_update(s);
5241
        if (reg == R_SS) {
5242
            /* if reg == SS, inhibit interrupts/trace. */
5243
            /* If several instructions disable interrupts, only the
5244
               _first_ does it */
5245
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
5246
                gen_helper_set_inhibit_irq(cpu_env);
5247
            s->tf = 0;
5248
        }
5249
        if (s->is_jmp) {
5250
            gen_jmp_im(s->pc - s->cs_base);
5251
            gen_eob(s);
5252
        }
5253
        break;
5254
    case 0x1a1: /* pop fs */
5255
    case 0x1a9: /* pop gs */
5256
        gen_pop_T0(s);
5257
        gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
5258
        gen_pop_update(s);
5259
        if (s->is_jmp) {
5260
            gen_jmp_im(s->pc - s->cs_base);
5261
            gen_eob(s);
5262
        }
5263
        break;
5264

    
5265
        /**************************/
5266
        /* mov */
5267
    case 0x88:
5268
    case 0x89: /* mov Gv, Ev */
5269
        if ((b & 1) == 0)
5270
            ot = OT_BYTE;
5271
        else
5272
            ot = dflag + OT_WORD;
5273
        modrm = cpu_ldub_code(env, s->pc++);
5274
        reg = ((modrm >> 3) & 7) | rex_r;
5275

    
5276
        /* generate a generic store */
5277
        gen_ldst_modrm(env, s, modrm, ot, reg, 1);
5278
        break;
5279
    case 0xc6:
5280
    case 0xc7: /* mov Ev, Iv */
5281
        if ((b & 1) == 0)
5282
            ot = OT_BYTE;
5283
        else
5284
            ot = dflag + OT_WORD;
5285
        modrm = cpu_ldub_code(env, s->pc++);
5286
        mod = (modrm >> 6) & 3;
5287
        if (mod != 3) {
5288
            s->rip_offset = insn_const_size(ot);
5289
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5290
        }
5291
        val = insn_get(env, s, ot);
5292
        gen_op_movl_T0_im(val);
5293
        if (mod != 3)
5294
            gen_op_st_T0_A0(ot + s->mem_index);
5295
        else
5296
            gen_op_mov_reg_T0(ot, (modrm & 7) | REX_B(s));
5297
        break;
5298
    case 0x8a:
5299
    case 0x8b: /* mov Ev, Gv */
5300
        if ((b & 1) == 0)
5301
            ot = OT_BYTE;
5302
        else
5303
            ot = OT_WORD + dflag;
5304
        modrm = cpu_ldub_code(env, s->pc++);
5305
        reg = ((modrm >> 3) & 7) | rex_r;
5306

    
5307
        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5308
        gen_op_mov_reg_T0(ot, reg);
5309
        break;
5310
    case 0x8e: /* mov seg, Gv */
5311
        modrm = cpu_ldub_code(env, s->pc++);
5312
        reg = (modrm >> 3) & 7;
5313
        if (reg >= 6 || reg == R_CS)
5314
            goto illegal_op;
5315
        gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
5316
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
5317
        if (reg == R_SS) {
5318
            /* if reg == SS, inhibit interrupts/trace */
5319
            /* If several instructions disable interrupts, only the
5320
               _first_ does it */
5321
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
5322
                gen_helper_set_inhibit_irq(cpu_env);
5323
            s->tf = 0;
5324
        }
5325
        if (s->is_jmp) {
5326
            gen_jmp_im(s->pc - s->cs_base);
5327
            gen_eob(s);
5328
        }
5329
        break;
5330
    case 0x8c: /* mov Gv, seg */
5331
        modrm = cpu_ldub_code(env, s->pc++);
5332
        reg = (modrm >> 3) & 7;
5333
        mod = (modrm >> 6) & 3;
5334
        if (reg >= 6)
5335
            goto illegal_op;
5336
        gen_op_movl_T0_seg(reg);
5337
        if (mod == 3)
5338
            ot = OT_WORD + dflag;
5339
        else
5340
            ot = OT_WORD;
5341
        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5342
        break;
5343

    
5344
    case 0x1b6: /* movzbS Gv, Eb */
5345
    case 0x1b7: /* movzwS Gv, Eb */
5346
    case 0x1be: /* movsbS Gv, Eb */
5347
    case 0x1bf: /* movswS Gv, Eb */
5348
        {
5349
            int d_ot;
5350
            /* d_ot is the size of destination */
5351
            d_ot = dflag + OT_WORD;
5352
            /* ot is the size of source */
5353
            ot = (b & 1) + OT_BYTE;
5354
            modrm = cpu_ldub_code(env, s->pc++);
5355
            reg = ((modrm >> 3) & 7) | rex_r;
5356
            mod = (modrm >> 6) & 3;
5357
            rm = (modrm & 7) | REX_B(s);
5358

    
5359
            if (mod == 3) {
5360
                gen_op_mov_TN_reg(ot, 0, rm);
5361
                switch(ot | (b & 8)) {
5362
                case OT_BYTE:
5363
                    tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
5364
                    break;
5365
                case OT_BYTE | 8:
5366
                    tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
5367
                    break;
5368
                case OT_WORD:
5369
                    tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
5370
                    break;
5371
                default:
5372
                case OT_WORD | 8:
5373
                    tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
5374
                    break;
5375
                }
5376
                gen_op_mov_reg_T0(d_ot, reg);
5377
            } else {
5378
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5379
                if (b & 8) {
5380
                    gen_op_lds_T0_A0(ot + s->mem_index);
5381
                } else {
5382
                    gen_op_ldu_T0_A0(ot + s->mem_index);
5383
                }
5384
                gen_op_mov_reg_T0(d_ot, reg);
5385
            }
5386
        }
5387
        break;
5388

    
5389
    case 0x8d: /* lea */
5390
        ot = dflag + OT_WORD;
5391
        modrm = cpu_ldub_code(env, s->pc++);
5392
        mod = (modrm >> 6) & 3;
5393
        if (mod == 3)
5394
            goto illegal_op;
5395
        reg = ((modrm >> 3) & 7) | rex_r;
5396
        /* we must ensure that no segment is added */
5397
        s->override = -1;
5398
        val = s->addseg;
5399
        s->addseg = 0;
5400
        gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5401
        s->addseg = val;
5402
        gen_op_mov_reg_A0(ot - OT_WORD, reg);
5403
        break;
5404

    
5405
    case 0xa0: /* mov EAX, Ov */
5406
    case 0xa1:
5407
    case 0xa2: /* mov Ov, EAX */
5408
    case 0xa3:
5409
        {
5410
            target_ulong offset_addr;
5411

    
5412
            if ((b & 1) == 0)
5413
                ot = OT_BYTE;
5414
            else
5415
                ot = dflag + OT_WORD;
5416
#ifdef TARGET_X86_64
5417
            if (s->aflag == 2) {
5418
                offset_addr = cpu_ldq_code(env, s->pc);
5419
                s->pc += 8;
5420
                gen_op_movq_A0_im(offset_addr);
5421
            } else
5422
#endif
5423
            {
5424
                if (s->aflag) {
5425
                    offset_addr = insn_get(env, s, OT_LONG);
5426
                } else {
5427
                    offset_addr = insn_get(env, s, OT_WORD);
5428
                }
5429
                gen_op_movl_A0_im(offset_addr);
5430
            }
5431
            gen_add_A0_ds_seg(s);
5432
            if ((b & 2) == 0) {
5433
                gen_op_ld_T0_A0(ot + s->mem_index);
5434
                gen_op_mov_reg_T0(ot, R_EAX);
5435
            } else {
5436
                gen_op_mov_TN_reg(ot, 0, R_EAX);
5437
                gen_op_st_T0_A0(ot + s->mem_index);
5438
            }
5439
        }
5440
        break;
5441
    case 0xd7: /* xlat */
5442
#ifdef TARGET_X86_64
5443
        if (s->aflag == 2) {
5444
            gen_op_movq_A0_reg(R_EBX);
5445
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
5446
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
5447
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
5448
        } else
5449
#endif
5450
        {
5451
            gen_op_movl_A0_reg(R_EBX);
5452
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
5453
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
5454
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
5455
            if (s->aflag == 0)
5456
                gen_op_andl_A0_ffff();
5457
            else
5458
                tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
5459
        }
5460
        gen_add_A0_ds_seg(s);
5461
        gen_op_ldu_T0_A0(OT_BYTE + s->mem_index);
5462
        gen_op_mov_reg_T0(OT_BYTE, R_EAX);
5463
        break;
5464
    case 0xb0 ... 0xb7: /* mov R, Ib */
5465
        val = insn_get(env, s, OT_BYTE);
5466
        gen_op_movl_T0_im(val);
5467
        gen_op_mov_reg_T0(OT_BYTE, (b & 7) | REX_B(s));
5468
        break;
5469
    case 0xb8 ... 0xbf: /* mov R, Iv */
5470
#ifdef TARGET_X86_64
5471
        if (dflag == 2) {
5472
            uint64_t tmp;
5473
            /* 64 bit case */
5474
            tmp = cpu_ldq_code(env, s->pc);
5475
            s->pc += 8;
5476
            reg = (b & 7) | REX_B(s);
5477
            gen_movtl_T0_im(tmp);
5478
            gen_op_mov_reg_T0(OT_QUAD, reg);
5479
        } else
5480
#endif
5481
        {
5482
            ot = dflag ? OT_LONG : OT_WORD;
5483
            val = insn_get(env, s, ot);
5484
            reg = (b & 7) | REX_B(s);
5485
            gen_op_movl_T0_im(val);
5486
            gen_op_mov_reg_T0(ot, reg);
5487
        }
5488
        break;
5489

    
5490
    case 0x91 ... 0x97: /* xchg R, EAX */
5491
    do_xchg_reg_eax:
5492
        ot = dflag + OT_WORD;
5493
        reg = (b & 7) | REX_B(s);
5494
        rm = R_EAX;
5495
        goto do_xchg_reg;
5496
    case 0x86:
5497
    case 0x87: /* xchg Ev, Gv */
5498
        if ((b & 1) == 0)
5499
            ot = OT_BYTE;
5500
        else
5501
            ot = dflag + OT_WORD;
5502
        modrm = cpu_ldub_code(env, s->pc++);
5503
        reg = ((modrm >> 3) & 7) | rex_r;
5504
        mod = (modrm >> 6) & 3;
5505
        if (mod == 3) {
5506
            rm = (modrm & 7) | REX_B(s);
5507
        do_xchg_reg:
5508
            gen_op_mov_TN_reg(ot, 0, reg);
5509
            gen_op_mov_TN_reg(ot, 1, rm);
5510
            gen_op_mov_reg_T0(ot, rm);
5511
            gen_op_mov_reg_T1(ot, reg);
5512
        } else {
5513
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5514
            gen_op_mov_TN_reg(ot, 0, reg);
5515
            /* for xchg, lock is implicit */
5516
            if (!(prefixes & PREFIX_LOCK))
5517
                gen_helper_lock();
5518
            gen_op_ld_T1_A0(ot + s->mem_index);
5519
            gen_op_st_T0_A0(ot + s->mem_index);
5520
            if (!(prefixes & PREFIX_LOCK))
5521
                gen_helper_unlock();
5522
            gen_op_mov_reg_T1(ot, reg);
5523
        }
5524
        break;
5525
    case 0xc4: /* les Gv */
5526
        /* In CODE64 this is VEX3; see above.  */
5527
        op = R_ES;
5528
        goto do_lxx;
5529
    case 0xc5: /* lds Gv */
5530
        /* In CODE64 this is VEX2; see above.  */
5531
        op = R_DS;
5532
        goto do_lxx;
5533
    case 0x1b2: /* lss Gv */
5534
        op = R_SS;
5535
        goto do_lxx;
5536
    case 0x1b4: /* lfs Gv */
5537
        op = R_FS;
5538
        goto do_lxx;
5539
    case 0x1b5: /* lgs Gv */
5540
        op = R_GS;
5541
    do_lxx:
5542
        ot = dflag ? OT_LONG : OT_WORD;
5543
        modrm = cpu_ldub_code(env, s->pc++);
5544
        reg = ((modrm >> 3) & 7) | rex_r;
5545
        mod = (modrm >> 6) & 3;
5546
        if (mod == 3)
5547
            goto illegal_op;
5548
        gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5549
        gen_op_ld_T1_A0(ot + s->mem_index);
5550
        gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
5551
        /* load the segment first to handle exceptions properly */
5552
        gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
5553
        gen_movl_seg_T0(s, op, pc_start - s->cs_base);
5554
        /* then put the data */
5555
        gen_op_mov_reg_T1(ot, reg);
5556
        if (s->is_jmp) {
5557
            gen_jmp_im(s->pc - s->cs_base);
5558
            gen_eob(s);
5559
        }
5560
        break;
5561

    
5562
        /************************/
5563
        /* shifts */
5564
    case 0xc0:
5565
    case 0xc1:
5566
        /* shift Ev,Ib */
5567
        shift = 2;
5568
    grp2:
5569
        {
5570
            if ((b & 1) == 0)
5571
                ot = OT_BYTE;
5572
            else
5573
                ot = dflag + OT_WORD;
5574

    
5575
            modrm = cpu_ldub_code(env, s->pc++);
5576
            mod = (modrm >> 6) & 3;
5577
            op = (modrm >> 3) & 7;
5578

    
5579
            if (mod != 3) {
5580
                if (shift == 2) {
5581
                    s->rip_offset = 1;
5582
                }
5583
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5584
                opreg = OR_TMP0;
5585
            } else {
5586
                opreg = (modrm & 7) | REX_B(s);
5587
            }
5588

    
5589
            /* simpler op */
5590
            if (shift == 0) {
5591
                gen_shift(s, op, ot, opreg, OR_ECX);
5592
            } else {
5593
                if (shift == 2) {
5594
                    shift = cpu_ldub_code(env, s->pc++);
5595
                }
5596
                gen_shifti(s, op, ot, opreg, shift);
5597
            }
5598
        }
5599
        break;
5600
    case 0xd0:
5601
    case 0xd1:
5602
        /* shift Ev,1 */
5603
        shift = 1;
5604
        goto grp2;
5605
    case 0xd2:
5606
    case 0xd3:
5607
        /* shift Ev,cl */
5608
        shift = 0;
5609
        goto grp2;
5610

    
5611
    case 0x1a4: /* shld imm */
5612
        op = 0;
5613
        shift = 1;
5614
        goto do_shiftd;
5615
    case 0x1a5: /* shld cl */
5616
        op = 0;
5617
        shift = 0;
5618
        goto do_shiftd;
5619
    case 0x1ac: /* shrd imm */
5620
        op = 1;
5621
        shift = 1;
5622
        goto do_shiftd;
5623
    case 0x1ad: /* shrd cl */
5624
        op = 1;
5625
        shift = 0;
5626
    do_shiftd:
5627
        ot = dflag + OT_WORD;
5628
        modrm = cpu_ldub_code(env, s->pc++);
5629
        mod = (modrm >> 6) & 3;
5630
        rm = (modrm & 7) | REX_B(s);
5631
        reg = ((modrm >> 3) & 7) | rex_r;
5632
        if (mod != 3) {
5633
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5634
            opreg = OR_TMP0;
5635
        } else {
5636
            opreg = rm;
5637
        }
5638
        gen_op_mov_TN_reg(ot, 1, reg);
5639

    
5640
        if (shift) {
5641
            TCGv imm = tcg_const_tl(cpu_ldub_code(env, s->pc++));
5642
            gen_shiftd_rm_T1(s, ot, opreg, op, imm);
5643
            tcg_temp_free(imm);
5644
        } else {
5645
            gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]);
5646
        }
5647
        break;
5648

    
5649
        /************************/
5650
        /* floats */
5651
    case 0xd8 ... 0xdf:
5652
        if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
5653
            /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5654
            /* XXX: what to do if illegal op ? */
5655
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5656
            break;
5657
        }
5658
        modrm = cpu_ldub_code(env, s->pc++);
5659
        mod = (modrm >> 6) & 3;
5660
        rm = modrm & 7;
5661
        op = ((b & 7) << 3) | ((modrm >> 3) & 7);
5662
        if (mod != 3) {
5663
            /* memory op */
5664
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5665
            switch(op) {
5666
            case 0x00 ... 0x07: /* fxxxs */
5667
            case 0x10 ... 0x17: /* fixxxl */
5668
            case 0x20 ... 0x27: /* fxxxl */
5669
            case 0x30 ... 0x37: /* fixxx */
5670
                {
5671
                    int op1;
5672
                    op1 = op & 7;
5673

    
5674
                    switch(op >> 4) {
5675
                    case 0:
5676
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5677
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5678
                        gen_helper_flds_FT0(cpu_env, cpu_tmp2_i32);
5679
                        break;
5680
                    case 1:
5681
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5682
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5683
                        gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5684
                        break;
5685
                    case 2:
5686
                        tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
5687
                                          (s->mem_index >> 2) - 1);
5688
                        gen_helper_fldl_FT0(cpu_env, cpu_tmp1_i64);
5689
                        break;
5690
                    case 3:
5691
                    default:
5692
                        gen_op_lds_T0_A0(OT_WORD + s->mem_index);
5693
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5694
                        gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5695
                        break;
5696
                    }
5697

    
5698
                    gen_helper_fp_arith_ST0_FT0(op1);
5699
                    if (op1 == 3) {
5700
                        /* fcomp needs pop */
5701
                        gen_helper_fpop(cpu_env);
5702
                    }
5703
                }
5704
                break;
5705
            case 0x08: /* flds */
5706
            case 0x0a: /* fsts */
5707
            case 0x0b: /* fstps */
5708
            case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5709
            case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5710
            case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5711
                switch(op & 7) {
5712
                case 0:
5713
                    switch(op >> 4) {
5714
                    case 0:
5715
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5716
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5717
                        gen_helper_flds_ST0(cpu_env, cpu_tmp2_i32);
5718
                        break;
5719
                    case 1:
5720
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5721
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5722
                        gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5723
                        break;
5724
                    case 2:
5725
                        tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
5726
                                          (s->mem_index >> 2) - 1);
5727
                        gen_helper_fldl_ST0(cpu_env, cpu_tmp1_i64);
5728
                        break;
5729
                    case 3:
5730
                    default:
5731
                        gen_op_lds_T0_A0(OT_WORD + s->mem_index);
5732
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5733
                        gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5734
                        break;
5735
                    }
5736
                    break;
5737
                case 1:
5738
                    /* XXX: the corresponding CPUID bit must be tested ! */
5739
                    switch(op >> 4) {
5740
                    case 1:
5741
                        gen_helper_fisttl_ST0(cpu_tmp2_i32, cpu_env);
5742
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5743
                        gen_op_st_T0_A0(OT_LONG + s->mem_index);
5744
                        break;
5745
                    case 2:
5746
                        gen_helper_fisttll_ST0(cpu_tmp1_i64, cpu_env);
5747
                        tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
5748
                                          (s->mem_index >> 2) - 1);
5749
                        break;
5750
                    case 3:
5751
                    default:
5752
                        gen_helper_fistt_ST0(cpu_tmp2_i32, cpu_env);
5753
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5754
                        gen_op_st_T0_A0(OT_WORD + s->mem_index);
5755
                        break;
5756
                    }
5757
                    gen_helper_fpop(cpu_env);
5758
                    break;
5759
                default:
5760
                    switch(op >> 4) {
5761
                    case 0:
5762
                        gen_helper_fsts_ST0(cpu_tmp2_i32, cpu_env);
5763
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5764
                        gen_op_st_T0_A0(OT_LONG + s->mem_index);
5765
                        break;
5766
                    case 1:
5767
                        gen_helper_fistl_ST0(cpu_tmp2_i32, cpu_env);
5768
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5769
                        gen_op_st_T0_A0(OT_LONG + s->mem_index);
5770
                        break;
5771
                    case 2:
5772
                        gen_helper_fstl_ST0(cpu_tmp1_i64, cpu_env);
5773
                        tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
5774
                                          (s->mem_index >> 2) - 1);
5775
                        break;
5776
                    case 3:
5777
                    default:
5778
                        gen_helper_fist_ST0(cpu_tmp2_i32, cpu_env);
5779
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5780
                        gen_op_st_T0_A0(OT_WORD + s->mem_index);
5781
                        break;
5782
                    }
5783
                    if ((op & 7) == 3)
5784
                        gen_helper_fpop(cpu_env);
5785
                    break;
5786
                }
5787
                break;
5788
            case 0x0c: /* fldenv mem */
5789
                gen_update_cc_op(s);
5790
                gen_jmp_im(pc_start - s->cs_base);
5791
                gen_helper_fldenv(cpu_env, cpu_A0, tcg_const_i32(s->dflag));
5792
                break;
5793
            case 0x0d: /* fldcw mem */
5794
                gen_op_ld_T0_A0(OT_WORD + s->mem_index);
5795
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5796
                gen_helper_fldcw(cpu_env, cpu_tmp2_i32);
5797
                break;
5798
            case 0x0e: /* fnstenv mem */
5799
                gen_update_cc_op(s);
5800
                gen_jmp_im(pc_start - s->cs_base);
5801
                gen_helper_fstenv(cpu_env, cpu_A0, tcg_const_i32(s->dflag));
5802
                break;
5803
            case 0x0f: /* fnstcw mem */
5804
                gen_helper_fnstcw(cpu_tmp2_i32, cpu_env);
5805
                tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5806
                gen_op_st_T0_A0(OT_WORD + s->mem_index);
5807
                break;
5808
            case 0x1d: /* fldt mem */
5809
                gen_update_cc_op(s);
5810
                gen_jmp_im(pc_start - s->cs_base);
5811
                gen_helper_fldt_ST0(cpu_env, cpu_A0);
5812
                break;
5813
            case 0x1f: /* fstpt mem */
5814
                gen_update_cc_op(s);
5815
                gen_jmp_im(pc_start - s->cs_base);
5816
                gen_helper_fstt_ST0(cpu_env, cpu_A0);
5817
                gen_helper_fpop(cpu_env);
5818
                break;
5819
            case 0x2c: /* frstor mem */
5820
                gen_update_cc_op(s);
5821
                gen_jmp_im(pc_start - s->cs_base);
5822
                gen_helper_frstor(cpu_env, cpu_A0, tcg_const_i32(s->dflag));
5823
                break;
5824
            case 0x2e: /* fnsave mem */
5825
                gen_update_cc_op(s);
5826
                gen_jmp_im(pc_start - s->cs_base);
5827
                gen_helper_fsave(cpu_env, cpu_A0, tcg_const_i32(s->dflag));
5828
                break;
5829
            case 0x2f: /* fnstsw mem */
5830
                gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
5831
                tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5832
                gen_op_st_T0_A0(OT_WORD + s->mem_index);
5833
                break;
5834
            case 0x3c: /* fbld */
5835
                gen_update_cc_op(s);
5836
                gen_jmp_im(pc_start - s->cs_base);
5837
                gen_helper_fbld_ST0(cpu_env, cpu_A0);
5838
                break;
5839
            case 0x3e: /* fbstp */
5840
                gen_update_cc_op(s);
5841
                gen_jmp_im(pc_start - s->cs_base);
5842
                gen_helper_fbst_ST0(cpu_env, cpu_A0);
5843
                gen_helper_fpop(cpu_env);
5844
                break;
5845
            case 0x3d: /* fildll */
5846
                tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
5847
                                  (s->mem_index >> 2) - 1);
5848
                gen_helper_fildll_ST0(cpu_env, cpu_tmp1_i64);
5849
                break;
5850
            case 0x3f: /* fistpll */
5851
                gen_helper_fistll_ST0(cpu_tmp1_i64, cpu_env);
5852
                tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
5853
                                  (s->mem_index >> 2) - 1);
5854
                gen_helper_fpop(cpu_env);
5855
                break;
5856
            default:
5857
                goto illegal_op;
5858
            }
5859
        } else {
5860
            /* register float ops */
5861
            opreg = rm;
5862

    
5863
            switch(op) {
5864
            case 0x08: /* fld sti */
5865
                gen_helper_fpush(cpu_env);
5866
                gen_helper_fmov_ST0_STN(cpu_env,
5867
                                        tcg_const_i32((opreg + 1) & 7));
5868
                break;
5869
            case 0x09: /* fxchg sti */
5870
            case 0x29: /* fxchg4 sti, undocumented op */
5871
            case 0x39: /* fxchg7 sti, undocumented op */
5872
                gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg));
5873
                break;
5874
            case 0x0a: /* grp d9/2 */
5875
                switch(rm) {
5876
                case 0: /* fnop */
5877
                    /* check exceptions (FreeBSD FPU probe) */
5878
                    gen_update_cc_op(s);
5879
                    gen_jmp_im(pc_start - s->cs_base);
5880
                    gen_helper_fwait(cpu_env);
5881
                    break;
5882
                default:
5883
                    goto illegal_op;
5884
                }
5885
                break;
5886
            case 0x0c: /* grp d9/4 */
5887
                switch(rm) {
5888
                case 0: /* fchs */
5889
                    gen_helper_fchs_ST0(cpu_env);
5890
                    break;
5891
                case 1: /* fabs */
5892
                    gen_helper_fabs_ST0(cpu_env);
5893
                    break;
5894
                case 4: /* ftst */
5895
                    gen_helper_fldz_FT0(cpu_env);
5896
                    gen_helper_fcom_ST0_FT0(cpu_env);
5897
                    break;
5898
                case 5: /* fxam */
5899
                    gen_helper_fxam_ST0(cpu_env);
5900
                    break;
5901
                default:
5902
                    goto illegal_op;
5903
                }
5904
                break;
5905
            case 0x0d: /* grp d9/5 */
5906
                {
5907
                    switch(rm) {
5908
                    case 0:
5909
                        gen_helper_fpush(cpu_env);
5910
                        gen_helper_fld1_ST0(cpu_env);
5911
                        break;
5912
                    case 1:
5913
                        gen_helper_fpush(cpu_env);
5914
                        gen_helper_fldl2t_ST0(cpu_env);
5915
                        break;
5916
                    case 2:
5917
                        gen_helper_fpush(cpu_env);
5918
                        gen_helper_fldl2e_ST0(cpu_env);
5919
                        break;
5920
                    case 3:
5921
                        gen_helper_fpush(cpu_env);
5922
                        gen_helper_fldpi_ST0(cpu_env);
5923
                        break;
5924
                    case 4:
5925
                        gen_helper_fpush(cpu_env);
5926
                        gen_helper_fldlg2_ST0(cpu_env);
5927
                        break;
5928
                    case 5:
5929
                        gen_helper_fpush(cpu_env);
5930
                        gen_helper_fldln2_ST0(cpu_env);
5931
                        break;
5932
                    case 6:
5933
                        gen_helper_fpush(cpu_env);
5934
                        gen_helper_fldz_ST0(cpu_env);
5935
                        break;
5936
                    default:
5937
                        goto illegal_op;
5938
                    }
5939
                }
5940
                break;
5941
            case 0x0e: /* grp d9/6 */
5942
                switch(rm) {
5943
                case 0: /* f2xm1 */
5944
                    gen_helper_f2xm1(cpu_env);
5945
                    break;
5946
                case 1: /* fyl2x */
5947
                    gen_helper_fyl2x(cpu_env);
5948
                    break;
5949
                case 2: /* fptan */
5950
                    gen_helper_fptan(cpu_env);
5951
                    break;
5952
                case 3: /* fpatan */
5953
                    gen_helper_fpatan(cpu_env);
5954
                    break;
5955
                case 4: /* fxtract */
5956
                    gen_helper_fxtract(cpu_env);
5957
                    break;
5958
                case 5: /* fprem1 */
5959
                    gen_helper_fprem1(cpu_env);
5960
                    break;
5961
                case 6: /* fdecstp */
5962
                    gen_helper_fdecstp(cpu_env);
5963
                    break;
5964
                default:
5965
                case 7: /* fincstp */
5966
                    gen_helper_fincstp(cpu_env);
5967
                    break;
5968
                }
5969
                break;
5970
            case 0x0f: /* grp d9/7 */
5971
                switch(rm) {
5972
                case 0: /* fprem */
5973
                    gen_helper_fprem(cpu_env);
5974
                    break;
5975
                case 1: /* fyl2xp1 */
5976
                    gen_helper_fyl2xp1(cpu_env);
5977
                    break;
5978
                case 2: /* fsqrt */
5979
                    gen_helper_fsqrt(cpu_env);
5980
                    break;
5981
                case 3: /* fsincos */
5982
                    gen_helper_fsincos(cpu_env);
5983
                    break;
5984
                case 5: /* fscale */
5985
                    gen_helper_fscale(cpu_env);
5986
                    break;
5987
                case 4: /* frndint */
5988
                    gen_helper_frndint(cpu_env);
5989
                    break;
5990
                case 6: /* fsin */
5991
                    gen_helper_fsin(cpu_env);
5992
                    break;
5993
                default:
5994
                case 7: /* fcos */
5995
                    gen_helper_fcos(cpu_env);
5996
                    break;
5997
                }
5998
                break;
5999
            case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6000
            case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6001
            case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6002
                {
6003
                    int op1;
6004

    
6005
                    op1 = op & 7;
6006
                    if (op >= 0x20) {
6007
                        gen_helper_fp_arith_STN_ST0(op1, opreg);
6008
                        if (op >= 0x30)
6009
                            gen_helper_fpop(cpu_env);
6010
                    } else {
6011
                        gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6012
                        gen_helper_fp_arith_ST0_FT0(op1);
6013
                    }
6014
                }
6015
                break;
6016
            case 0x02: /* fcom */
6017
            case 0x22: /* fcom2, undocumented op */
6018
                gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6019
                gen_helper_fcom_ST0_FT0(cpu_env);
6020
                break;
6021
            case 0x03: /* fcomp */
6022
            case 0x23: /* fcomp3, undocumented op */
6023
            case 0x32: /* fcomp5, undocumented op */
6024
                gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6025
                gen_helper_fcom_ST0_FT0(cpu_env);
6026
                gen_helper_fpop(cpu_env);
6027
                break;
6028
            case 0x15: /* da/5 */
6029
                switch(rm) {
6030
                case 1: /* fucompp */
6031
                    gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6032
                    gen_helper_fucom_ST0_FT0(cpu_env);
6033
                    gen_helper_fpop(cpu_env);
6034
                    gen_helper_fpop(cpu_env);
6035
                    break;
6036
                default:
6037
                    goto illegal_op;
6038
                }
6039
                break;
6040
            case 0x1c:
6041
                switch(rm) {
6042
                case 0: /* feni (287 only, just do nop here) */
6043
                    break;
6044
                case 1: /* fdisi (287 only, just do nop here) */
6045
                    break;
6046
                case 2: /* fclex */
6047
                    gen_helper_fclex(cpu_env);
6048
                    break;
6049
                case 3: /* fninit */
6050
                    gen_helper_fninit(cpu_env);
6051
                    break;
6052
                case 4: /* fsetpm (287 only, just do nop here) */
6053
                    break;
6054
                default:
6055
                    goto illegal_op;
6056
                }
6057
                break;
6058
            case 0x1d: /* fucomi */
6059
                gen_update_cc_op(s);
6060
                gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6061
                gen_helper_fucomi_ST0_FT0(cpu_env);
6062
                set_cc_op(s, CC_OP_EFLAGS);
6063
                break;
6064
            case 0x1e: /* fcomi */
6065
                gen_update_cc_op(s);
6066
                gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6067
                gen_helper_fcomi_ST0_FT0(cpu_env);
6068
                set_cc_op(s, CC_OP_EFLAGS);
6069
                break;
6070
            case 0x28: /* ffree sti */
6071
                gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6072
                break;
6073
            case 0x2a: /* fst sti */
6074
                gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6075
                break;
6076
            case 0x2b: /* fstp sti */
6077
            case 0x0b: /* fstp1 sti, undocumented op */
6078
            case 0x3a: /* fstp8 sti, undocumented op */
6079
            case 0x3b: /* fstp9 sti, undocumented op */
6080
                gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6081
                gen_helper_fpop(cpu_env);
6082
                break;
6083
            case 0x2c: /* fucom st(i) */
6084
                gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6085
                gen_helper_fucom_ST0_FT0(cpu_env);
6086
                break;
6087
            case 0x2d: /* fucomp st(i) */
6088
                gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6089
                gen_helper_fucom_ST0_FT0(cpu_env);
6090
                gen_helper_fpop(cpu_env);
6091
                break;
6092
            case 0x33: /* de/3 */
6093
                switch(rm) {
6094
                case 1: /* fcompp */
6095
                    gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6096
                    gen_helper_fcom_ST0_FT0(cpu_env);
6097
                    gen_helper_fpop(cpu_env);
6098
                    gen_helper_fpop(cpu_env);
6099
                    break;
6100
                default:
6101
                    goto illegal_op;
6102
                }
6103
                break;
6104
            case 0x38: /* ffreep sti, undocumented op */
6105
                gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6106
                gen_helper_fpop(cpu_env);
6107
                break;
6108
            case 0x3c: /* df/4 */
6109
                switch(rm) {
6110
                case 0:
6111
                    gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
6112
                    tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
6113
                    gen_op_mov_reg_T0(OT_WORD, R_EAX);
6114
                    break;
6115
                default:
6116
                    goto illegal_op;
6117
                }
6118
                break;
6119
            case 0x3d: /* fucomip */
6120
                gen_update_cc_op(s);
6121
                gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6122
                gen_helper_fucomi_ST0_FT0(cpu_env);
6123
                gen_helper_fpop(cpu_env);
6124
                set_cc_op(s, CC_OP_EFLAGS);
6125
                break;
6126
            case 0x3e: /* fcomip */
6127
                gen_update_cc_op(s);
6128
                gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6129
                gen_helper_fcomi_ST0_FT0(cpu_env);
6130
                gen_helper_fpop(cpu_env);
6131
                set_cc_op(s, CC_OP_EFLAGS);
6132
                break;
6133
            case 0x10 ... 0x13: /* fcmovxx */
6134
            case 0x18 ... 0x1b:
6135
                {
6136
                    int op1, l1;
6137
                    static const uint8_t fcmov_cc[8] = {
6138
                        (JCC_B << 1),
6139
                        (JCC_Z << 1),
6140
                        (JCC_BE << 1),
6141
                        (JCC_P << 1),
6142
                    };
6143
                    op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
6144
                    l1 = gen_new_label();
6145
                    gen_jcc1_noeob(s, op1, l1);
6146
                    gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg));
6147
                    gen_set_label(l1);
6148
                }
6149
                break;
6150
            default:
6151
                goto illegal_op;
6152
            }
6153
        }
6154
        break;
6155
        /************************/
6156
        /* string ops */
6157

    
6158
    case 0xa4: /* movsS */
6159
    case 0xa5:
6160
        if ((b & 1) == 0)
6161
            ot = OT_BYTE;
6162
        else
6163
            ot = dflag + OT_WORD;
6164

    
6165
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6166
            gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6167
        } else {
6168
            gen_movs(s, ot);
6169
        }
6170
        break;
6171

    
6172
    case 0xaa: /* stosS */
6173
    case 0xab:
6174
        if ((b & 1) == 0)
6175
            ot = OT_BYTE;
6176
        else
6177
            ot = dflag + OT_WORD;
6178

    
6179
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6180
            gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6181
        } else {
6182
            gen_stos(s, ot);
6183
        }
6184
        break;
6185
    case 0xac: /* lodsS */
6186
    case 0xad:
6187
        if ((b & 1) == 0)
6188
            ot = OT_BYTE;
6189
        else
6190
            ot = dflag + OT_WORD;
6191
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6192
            gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6193
        } else {
6194
            gen_lods(s, ot);
6195
        }
6196
        break;
6197
    case 0xae: /* scasS */
6198
    case 0xaf:
6199
        if ((b & 1) == 0)
6200
            ot = OT_BYTE;
6201
        else
6202
            ot = dflag + OT_WORD;
6203
        if (prefixes & PREFIX_REPNZ) {
6204
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6205
        } else if (prefixes & PREFIX_REPZ) {
6206
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6207
        } else {
6208
            gen_scas(s, ot);
6209
        }
6210
        break;
6211

    
6212
    case 0xa6: /* cmpsS */
6213
    case 0xa7:
6214
        if ((b & 1) == 0)
6215
            ot = OT_BYTE;
6216
        else
6217
            ot = dflag + OT_WORD;
6218
        if (prefixes & PREFIX_REPNZ) {
6219
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6220
        } else if (prefixes & PREFIX_REPZ) {
6221
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6222
        } else {
6223
            gen_cmps(s, ot);
6224
        }
6225
        break;
6226
    case 0x6c: /* insS */
6227
    case 0x6d:
6228
        if ((b & 1) == 0)
6229
            ot = OT_BYTE;
6230
        else
6231
            ot = dflag ? OT_LONG : OT_WORD;
6232
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6233
        gen_op_andl_T0_ffff();
6234
        gen_check_io(s, ot, pc_start - s->cs_base, 
6235
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
6236
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6237
            gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6238
        } else {
6239
            gen_ins(s, ot);
6240
            if (use_icount) {
6241
                gen_jmp(s, s->pc - s->cs_base);
6242
            }
6243
        }
6244
        break;
6245
    case 0x6e: /* outsS */
6246
    case 0x6f:
6247
        if ((b & 1) == 0)
6248
            ot = OT_BYTE;
6249
        else
6250
            ot = dflag ? OT_LONG : OT_WORD;
6251
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6252
        gen_op_andl_T0_ffff();
6253
        gen_check_io(s, ot, pc_start - s->cs_base,
6254
                     svm_is_rep(prefixes) | 4);
6255
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6256
            gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6257
        } else {
6258
            gen_outs(s, ot);
6259
            if (use_icount) {
6260
                gen_jmp(s, s->pc - s->cs_base);
6261
            }
6262
        }
6263
        break;
6264

    
6265
        /************************/
6266
        /* port I/O */
6267

    
6268
    case 0xe4:
6269
    case 0xe5:
6270
        if ((b & 1) == 0)
6271
            ot = OT_BYTE;
6272
        else
6273
            ot = dflag ? OT_LONG : OT_WORD;
6274
        val = cpu_ldub_code(env, s->pc++);
6275
        gen_op_movl_T0_im(val);
6276
        gen_check_io(s, ot, pc_start - s->cs_base,
6277
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6278
        if (use_icount)
6279
            gen_io_start();
6280
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6281
        gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
6282
        gen_op_mov_reg_T1(ot, R_EAX);
6283
        if (use_icount) {
6284
            gen_io_end();
6285
            gen_jmp(s, s->pc - s->cs_base);
6286
        }
6287
        break;
6288
    case 0xe6:
6289
    case 0xe7:
6290
        if ((b & 1) == 0)
6291
            ot = OT_BYTE;
6292
        else
6293
            ot = dflag ? OT_LONG : OT_WORD;
6294
        val = cpu_ldub_code(env, s->pc++);
6295
        gen_op_movl_T0_im(val);
6296
        gen_check_io(s, ot, pc_start - s->cs_base,
6297
                     svm_is_rep(prefixes));
6298
        gen_op_mov_TN_reg(ot, 1, R_EAX);
6299

    
6300
        if (use_icount)
6301
            gen_io_start();
6302
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6303
        tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
6304
        gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6305
        if (use_icount) {
6306
            gen_io_end();
6307
            gen_jmp(s, s->pc - s->cs_base);
6308
        }
6309
        break;
6310
    case 0xec:
6311
    case 0xed:
6312
        if ((b & 1) == 0)
6313
            ot = OT_BYTE;
6314
        else
6315
            ot = dflag ? OT_LONG : OT_WORD;
6316
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6317
        gen_op_andl_T0_ffff();
6318
        gen_check_io(s, ot, pc_start - s->cs_base,
6319
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6320
        if (use_icount)
6321
            gen_io_start();
6322
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6323
        gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
6324
        gen_op_mov_reg_T1(ot, R_EAX);
6325
        if (use_icount) {
6326
            gen_io_end();
6327
            gen_jmp(s, s->pc - s->cs_base);
6328
        }
6329
        break;
6330
    case 0xee:
6331
    case 0xef:
6332
        if ((b & 1) == 0)
6333
            ot = OT_BYTE;
6334
        else
6335
            ot = dflag ? OT_LONG : OT_WORD;
6336
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6337
        gen_op_andl_T0_ffff();
6338
        gen_check_io(s, ot, pc_start - s->cs_base,
6339
                     svm_is_rep(prefixes));
6340
        gen_op_mov_TN_reg(ot, 1, R_EAX);
6341

    
6342
        if (use_icount)
6343
            gen_io_start();
6344
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6345
        tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
6346
        gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6347
        if (use_icount) {
6348
            gen_io_end();
6349
            gen_jmp(s, s->pc - s->cs_base);
6350
        }
6351
        break;
6352

    
6353
        /************************/
6354
        /* control */
6355
    case 0xc2: /* ret im */
6356
        val = cpu_ldsw_code(env, s->pc);
6357
        s->pc += 2;
6358
        gen_pop_T0(s);
6359
        if (CODE64(s) && s->dflag)
6360
            s->dflag = 2;
6361
        gen_stack_update(s, val + (2 << s->dflag));
6362
        if (s->dflag == 0)
6363
            gen_op_andl_T0_ffff();
6364
        gen_op_jmp_T0();
6365
        gen_eob(s);
6366
        break;
6367
    case 0xc3: /* ret */
6368
        gen_pop_T0(s);
6369
        gen_pop_update(s);
6370
        if (s->dflag == 0)
6371
            gen_op_andl_T0_ffff();
6372
        gen_op_jmp_T0();
6373
        gen_eob(s);
6374
        break;
6375
    case 0xca: /* lret im */
6376
        val = cpu_ldsw_code(env, s->pc);
6377
        s->pc += 2;
6378
    do_lret:
6379
        if (s->pe && !s->vm86) {
6380
            gen_update_cc_op(s);
6381
            gen_jmp_im(pc_start - s->cs_base);
6382
            gen_helper_lret_protected(cpu_env, tcg_const_i32(s->dflag),
6383
                                      tcg_const_i32(val));
6384
        } else {
6385
            gen_stack_A0(s);
6386
            /* pop offset */
6387
            gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
6388
            if (s->dflag == 0)
6389
                gen_op_andl_T0_ffff();
6390
            /* NOTE: keeping EIP updated is not a problem in case of
6391
               exception */
6392
            gen_op_jmp_T0();
6393
            /* pop selector */
6394
            gen_op_addl_A0_im(2 << s->dflag);
6395
            gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
6396
            gen_op_movl_seg_T0_vm(R_CS);
6397
            /* add stack offset */
6398
            gen_stack_update(s, val + (4 << s->dflag));
6399
        }
6400
        gen_eob(s);
6401
        break;
6402
    case 0xcb: /* lret */
6403
        val = 0;
6404
        goto do_lret;
6405
    case 0xcf: /* iret */
6406
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
6407
        if (!s->pe) {
6408
            /* real mode */
6409
            gen_helper_iret_real(cpu_env, tcg_const_i32(s->dflag));
6410
            set_cc_op(s, CC_OP_EFLAGS);
6411
        } else if (s->vm86) {
6412
            if (s->iopl != 3) {
6413
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6414
            } else {
6415
                gen_helper_iret_real(cpu_env, tcg_const_i32(s->dflag));
6416
                set_cc_op(s, CC_OP_EFLAGS);
6417
            }
6418
        } else {
6419
            gen_update_cc_op(s);
6420
            gen_jmp_im(pc_start - s->cs_base);
6421
            gen_helper_iret_protected(cpu_env, tcg_const_i32(s->dflag),
6422
                                      tcg_const_i32(s->pc - s->cs_base));
6423
            set_cc_op(s, CC_OP_EFLAGS);
6424
        }
6425
        gen_eob(s);
6426
        break;
6427
    case 0xe8: /* call im */
6428
        {
6429
            if (dflag)
6430
                tval = (int32_t)insn_get(env, s, OT_LONG);
6431
            else
6432
                tval = (int16_t)insn_get(env, s, OT_WORD);
6433
            next_eip = s->pc - s->cs_base;
6434
            tval += next_eip;
6435
            if (s->dflag == 0)
6436
                tval &= 0xffff;
6437
            else if(!CODE64(s))
6438
                tval &= 0xffffffff;
6439
            gen_movtl_T0_im(next_eip);
6440
            gen_push_T0(s);
6441
            gen_jmp(s, tval);
6442
        }
6443
        break;
6444
    case 0x9a: /* lcall im */
6445
        {
6446
            unsigned int selector, offset;
6447

    
6448
            if (CODE64(s))
6449
                goto illegal_op;
6450
            ot = dflag ? OT_LONG : OT_WORD;
6451
            offset = insn_get(env, s, ot);
6452
            selector = insn_get(env, s, OT_WORD);
6453

    
6454
            gen_op_movl_T0_im(selector);
6455
            gen_op_movl_T1_imu(offset);
6456
        }
6457
        goto do_lcall;
6458
    case 0xe9: /* jmp im */
6459
        if (dflag)
6460
            tval = (int32_t)insn_get(env, s, OT_LONG);
6461
        else
6462
            tval = (int16_t)insn_get(env, s, OT_WORD);
6463
        tval += s->pc - s->cs_base;
6464
        if (s->dflag == 0)
6465
            tval &= 0xffff;
6466
        else if(!CODE64(s))
6467
            tval &= 0xffffffff;
6468
        gen_jmp(s, tval);
6469
        break;
6470
    case 0xea: /* ljmp im */
6471
        {
6472
            unsigned int selector, offset;
6473

    
6474
            if (CODE64(s))
6475
                goto illegal_op;
6476
            ot = dflag ? OT_LONG : OT_WORD;
6477
            offset = insn_get(env, s, ot);
6478
            selector = insn_get(env, s, OT_WORD);
6479

    
6480
            gen_op_movl_T0_im(selector);
6481
            gen_op_movl_T1_imu(offset);
6482
        }
6483
        goto do_ljmp;
6484
    case 0xeb: /* jmp Jb */
6485
        tval = (int8_t)insn_get(env, s, OT_BYTE);
6486
        tval += s->pc - s->cs_base;
6487
        if (s->dflag == 0)
6488
            tval &= 0xffff;
6489
        gen_jmp(s, tval);
6490
        break;
6491
    case 0x70 ... 0x7f: /* jcc Jb */
6492
        tval = (int8_t)insn_get(env, s, OT_BYTE);
6493
        goto do_jcc;
6494
    case 0x180 ... 0x18f: /* jcc Jv */
6495
        if (dflag) {
6496
            tval = (int32_t)insn_get(env, s, OT_LONG);
6497
        } else {
6498
            tval = (int16_t)insn_get(env, s, OT_WORD);
6499
        }
6500
    do_jcc:
6501
        next_eip = s->pc - s->cs_base;
6502
        tval += next_eip;
6503
        if (s->dflag == 0)
6504
            tval &= 0xffff;
6505
        gen_jcc(s, b, tval, next_eip);
6506
        break;
6507

    
6508
    case 0x190 ... 0x19f: /* setcc Gv */
6509
        modrm = cpu_ldub_code(env, s->pc++);
6510
        gen_setcc1(s, b, cpu_T[0]);
6511
        gen_ldst_modrm(env, s, modrm, OT_BYTE, OR_TMP0, 1);
6512
        break;
6513
    case 0x140 ... 0x14f: /* cmov Gv, Ev */
6514
        ot = dflag + OT_WORD;
6515
        modrm = cpu_ldub_code(env, s->pc++);
6516
        reg = ((modrm >> 3) & 7) | rex_r;
6517
        gen_cmovcc1(env, s, ot, b, modrm, reg);
6518
        break;
6519

    
6520
        /************************/
6521
        /* flags */
6522
    case 0x9c: /* pushf */
6523
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
6524
        if (s->vm86 && s->iopl != 3) {
6525
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6526
        } else {
6527
            gen_update_cc_op(s);
6528
            gen_helper_read_eflags(cpu_T[0], cpu_env);
6529
            gen_push_T0(s);
6530
        }
6531
        break;
6532
    case 0x9d: /* popf */
6533
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
6534
        if (s->vm86 && s->iopl != 3) {
6535
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6536
        } else {
6537
            gen_pop_T0(s);
6538
            if (s->cpl == 0) {
6539
                if (s->dflag) {
6540
                    gen_helper_write_eflags(cpu_env, cpu_T[0],
6541
                                            tcg_const_i32((TF_MASK | AC_MASK |
6542
                                                           ID_MASK | NT_MASK |
6543
                                                           IF_MASK |
6544
                                                           IOPL_MASK)));
6545
                } else {
6546
                    gen_helper_write_eflags(cpu_env, cpu_T[0],
6547
                                            tcg_const_i32((TF_MASK | AC_MASK |
6548
                                                           ID_MASK | NT_MASK |
6549
                                                           IF_MASK | IOPL_MASK)
6550
                                                          & 0xffff));
6551
                }
6552
            } else {
6553
                if (s->cpl <= s->iopl) {
6554
                    if (s->dflag) {
6555
                        gen_helper_write_eflags(cpu_env, cpu_T[0],
6556
                                                tcg_const_i32((TF_MASK |
6557
                                                               AC_MASK |
6558
                                                               ID_MASK |
6559
                                                               NT_MASK |
6560
                                                               IF_MASK)));
6561
                    } else {
6562
                        gen_helper_write_eflags(cpu_env, cpu_T[0],
6563
                                                tcg_const_i32((TF_MASK |
6564
                                                               AC_MASK |
6565
                                                               ID_MASK |
6566
                                                               NT_MASK |
6567
                                                               IF_MASK)
6568
                                                              & 0xffff));
6569
                    }
6570
                } else {
6571
                    if (s->dflag) {
6572
                        gen_helper_write_eflags(cpu_env, cpu_T[0],
6573
                                           tcg_const_i32((TF_MASK | AC_MASK |
6574
                                                          ID_MASK | NT_MASK)));
6575
                    } else {
6576
                        gen_helper_write_eflags(cpu_env, cpu_T[0],
6577
                                           tcg_const_i32((TF_MASK | AC_MASK |
6578
                                                          ID_MASK | NT_MASK)
6579
                                                         & 0xffff));
6580
                    }
6581
                }
6582
            }
6583
            gen_pop_update(s);
6584
            set_cc_op(s, CC_OP_EFLAGS);
6585
            /* abort translation because TF/AC flag may change */
6586
            gen_jmp_im(s->pc - s->cs_base);
6587
            gen_eob(s);
6588
        }
6589
        break;
6590
    case 0x9e: /* sahf */
6591
        if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6592
            goto illegal_op;
6593
        gen_op_mov_TN_reg(OT_BYTE, 0, R_AH);
6594
        gen_compute_eflags(s);
6595
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
6596
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], CC_S | CC_Z | CC_A | CC_P | CC_C);
6597
        tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T[0]);
6598
        break;
6599
    case 0x9f: /* lahf */
6600
        if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6601
            goto illegal_op;
6602
        gen_compute_eflags(s);
6603
        /* Note: gen_compute_eflags() only gives the condition codes */
6604
        tcg_gen_ori_tl(cpu_T[0], cpu_cc_src, 0x02);
6605
        gen_op_mov_reg_T0(OT_BYTE, R_AH);
6606
        break;
6607
    case 0xf5: /* cmc */
6608
        gen_compute_eflags(s);
6609
        tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6610
        break;
6611
    case 0xf8: /* clc */
6612
        gen_compute_eflags(s);
6613
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
6614
        break;
6615
    case 0xf9: /* stc */
6616
        gen_compute_eflags(s);
6617
        tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6618
        break;
6619
    case 0xfc: /* cld */
6620
        tcg_gen_movi_i32(cpu_tmp2_i32, 1);
6621
        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6622
        break;
6623
    case 0xfd: /* std */
6624
        tcg_gen_movi_i32(cpu_tmp2_i32, -1);
6625
        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6626
        break;
6627

    
6628
        /************************/
6629
        /* bit operations */
6630
    case 0x1ba: /* bt/bts/btr/btc Gv, im */
6631
        ot = dflag + OT_WORD;
6632
        modrm = cpu_ldub_code(env, s->pc++);
6633
        op = (modrm >> 3) & 7;
6634
        mod = (modrm >> 6) & 3;
6635
        rm = (modrm & 7) | REX_B(s);
6636
        if (mod != 3) {
6637
            s->rip_offset = 1;
6638
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
6639
            gen_op_ld_T0_A0(ot + s->mem_index);
6640
        } else {
6641
            gen_op_mov_TN_reg(ot, 0, rm);
6642
        }
6643
        /* load shift */
6644
        val = cpu_ldub_code(env, s->pc++);
6645
        gen_op_movl_T1_im(val);
6646
        if (op < 4)
6647
            goto illegal_op;
6648
        op -= 4;
6649
        goto bt_op;
6650
    case 0x1a3: /* bt Gv, Ev */
6651
        op = 0;
6652
        goto do_btx;
6653
    case 0x1ab: /* bts */
6654
        op = 1;
6655
        goto do_btx;
6656
    case 0x1b3: /* btr */
6657
        op = 2;
6658
        goto do_btx;
6659
    case 0x1bb: /* btc */
6660
        op = 3;
6661
    do_btx:
6662
        ot = dflag + OT_WORD;
6663
        modrm = cpu_ldub_code(env, s->pc++);
6664
        reg = ((modrm >> 3) & 7) | rex_r;
6665
        mod = (modrm >> 6) & 3;
6666
        rm = (modrm & 7) | REX_B(s);
6667
        gen_op_mov_TN_reg(OT_LONG, 1, reg);
6668
        if (mod != 3) {
6669
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
6670
            /* specific case: we need to add a displacement */
6671
            gen_exts(ot, cpu_T[1]);
6672
            tcg_gen_sari_tl(cpu_tmp0, cpu_T[1], 3 + ot);
6673
            tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
6674
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
6675
            gen_op_ld_T0_A0(ot + s->mem_index);
6676
        } else {
6677
            gen_op_mov_TN_reg(ot, 0, rm);
6678
        }
6679
    bt_op:
6680
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], (1 << (3 + ot)) - 1);
6681
        switch(op) {
6682
        case 0:
6683
            tcg_gen_shr_tl(cpu_cc_src, cpu_T[0], cpu_T[1]);
6684
            tcg_gen_movi_tl(cpu_cc_dst, 0);
6685
            break;
6686
        case 1:
6687
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6688
            tcg_gen_movi_tl(cpu_tmp0, 1);
6689
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6690
            tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6691
            break;
6692
        case 2:
6693
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6694
            tcg_gen_movi_tl(cpu_tmp0, 1);
6695
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6696
            tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
6697
            tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6698
            break;
6699
        default:
6700
        case 3:
6701
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6702
            tcg_gen_movi_tl(cpu_tmp0, 1);
6703
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6704
            tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6705
            break;
6706
        }
6707
        set_cc_op(s, CC_OP_SARB + ot);
6708
        if (op != 0) {
6709
            if (mod != 3)
6710
                gen_op_st_T0_A0(ot + s->mem_index);
6711
            else
6712
                gen_op_mov_reg_T0(ot, rm);
6713
            tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
6714
            tcg_gen_movi_tl(cpu_cc_dst, 0);
6715
        }
6716
        break;
6717
    case 0x1bc: /* bsf */
6718
    case 0x1bd: /* bsr */
6719
        {
6720
            int label1;
6721
            TCGv t0;
6722

    
6723
            ot = dflag + OT_WORD;
6724
            modrm = cpu_ldub_code(env, s->pc++);
6725
            reg = ((modrm >> 3) & 7) | rex_r;
6726
            gen_ldst_modrm(env, s,modrm, ot, OR_TMP0, 0);
6727
            gen_extu(ot, cpu_T[0]);
6728
            t0 = tcg_temp_local_new();
6729
            tcg_gen_mov_tl(t0, cpu_T[0]);
6730
            if ((b & 1) && (prefixes & PREFIX_REPZ) &&
6731
                (s->cpuid_ext3_features & CPUID_EXT3_ABM)) {
6732
                switch(ot) {
6733
                case OT_WORD: gen_helper_lzcnt(cpu_T[0], t0,
6734
                    tcg_const_i32(16)); break;
6735
                case OT_LONG: gen_helper_lzcnt(cpu_T[0], t0,
6736
                    tcg_const_i32(32)); break;
6737
                case OT_QUAD: gen_helper_lzcnt(cpu_T[0], t0,
6738
                    tcg_const_i32(64)); break;
6739
                }
6740
                gen_op_mov_reg_T0(ot, reg);
6741
            } else {
6742
                label1 = gen_new_label();
6743
                tcg_gen_movi_tl(cpu_cc_dst, 0);
6744
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, label1);
6745
                if (b & 1) {
6746
                    gen_helper_bsr(cpu_T[0], t0);
6747
                } else {
6748
                    gen_helper_bsf(cpu_T[0], t0);
6749
                }
6750
                gen_op_mov_reg_T0(ot, reg);
6751
                tcg_gen_movi_tl(cpu_cc_dst, 1);
6752
                gen_set_label(label1);
6753
                set_cc_op(s, CC_OP_LOGICB + ot);
6754
            }
6755
            tcg_temp_free(t0);
6756
        }
6757
        break;
6758
        /************************/
6759
        /* bcd */
6760
    case 0x27: /* daa */
6761
        if (CODE64(s))
6762
            goto illegal_op;
6763
        gen_update_cc_op(s);
6764
        gen_helper_daa(cpu_env);
6765
        set_cc_op(s, CC_OP_EFLAGS);
6766
        break;
6767
    case 0x2f: /* das */
6768
        if (CODE64(s))
6769
            goto illegal_op;
6770
        gen_update_cc_op(s);
6771
        gen_helper_das(cpu_env);
6772
        set_cc_op(s, CC_OP_EFLAGS);
6773
        break;
6774
    case 0x37: /* aaa */
6775
        if (CODE64(s))
6776
            goto illegal_op;
6777
        gen_update_cc_op(s);
6778
        gen_helper_aaa(cpu_env);
6779
        set_cc_op(s, CC_OP_EFLAGS);
6780
        break;
6781
    case 0x3f: /* aas */
6782
        if (CODE64(s))
6783
            goto illegal_op;
6784
        gen_update_cc_op(s);
6785
        gen_helper_aas(cpu_env);
6786
        set_cc_op(s, CC_OP_EFLAGS);
6787
        break;
6788
    case 0xd4: /* aam */
6789
        if (CODE64(s))
6790
            goto illegal_op;
6791
        val = cpu_ldub_code(env, s->pc++);
6792
        if (val == 0) {
6793
            gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
6794
        } else {
6795
            gen_helper_aam(cpu_env, tcg_const_i32(val));
6796
            set_cc_op(s, CC_OP_LOGICB);
6797
        }
6798
        break;
6799
    case 0xd5: /* aad */
6800
        if (CODE64(s))
6801
            goto illegal_op;
6802
        val = cpu_ldub_code(env, s->pc++);
6803
        gen_helper_aad(cpu_env, tcg_const_i32(val));
6804
        set_cc_op(s, CC_OP_LOGICB);
6805
        break;
6806
        /************************/
6807
        /* misc */
6808
    case 0x90: /* nop */
6809
        /* XXX: correct lock test for all insn */
6810
        if (prefixes & PREFIX_LOCK) {
6811
            goto illegal_op;
6812
        }
6813
        /* If REX_B is set, then this is xchg eax, r8d, not a nop.  */
6814
        if (REX_B(s)) {
6815
            goto do_xchg_reg_eax;
6816
        }
6817
        if (prefixes & PREFIX_REPZ) {
6818
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_PAUSE);
6819
        }
6820
        break;
6821
    case 0x9b: /* fwait */
6822
        if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
6823
            (HF_MP_MASK | HF_TS_MASK)) {
6824
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6825
        } else {
6826
            gen_update_cc_op(s);
6827
            gen_jmp_im(pc_start - s->cs_base);
6828
            gen_helper_fwait(cpu_env);
6829
        }
6830
        break;
6831
    case 0xcc: /* int3 */
6832
        gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
6833
        break;
6834
    case 0xcd: /* int N */
6835
        val = cpu_ldub_code(env, s->pc++);
6836
        if (s->vm86 && s->iopl != 3) {
6837
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6838
        } else {
6839
            gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
6840
        }
6841
        break;
6842
    case 0xce: /* into */
6843
        if (CODE64(s))
6844
            goto illegal_op;
6845
        gen_update_cc_op(s);
6846
        gen_jmp_im(pc_start - s->cs_base);
6847
        gen_helper_into(cpu_env, tcg_const_i32(s->pc - pc_start));
6848
        break;
6849
#ifdef WANT_ICEBP
6850
    case 0xf1: /* icebp (undocumented, exits to external debugger) */
6851
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
6852
#if 1
6853
        gen_debug(s, pc_start - s->cs_base);
6854
#else
6855
        /* start debug */
6856
        tb_flush(env);
6857
        qemu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
6858
#endif
6859
        break;
6860
#endif
6861
    case 0xfa: /* cli */
6862
        if (!s->vm86) {
6863
            if (s->cpl <= s->iopl) {
6864
                gen_helper_cli(cpu_env);
6865
            } else {
6866
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6867
            }
6868
        } else {
6869
            if (s->iopl == 3) {
6870
                gen_helper_cli(cpu_env);
6871
            } else {
6872
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6873
            }
6874
        }
6875
        break;
6876
    case 0xfb: /* sti */
6877
        if (!s->vm86) {
6878
            if (s->cpl <= s->iopl) {
6879
            gen_sti:
6880
                gen_helper_sti(cpu_env);
6881
                /* interruptions are enabled only the first insn after sti */
6882
                /* If several instructions disable interrupts, only the
6883
                   _first_ does it */
6884
                if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
6885
                    gen_helper_set_inhibit_irq(cpu_env);
6886
                /* give a chance to handle pending irqs */
6887
                gen_jmp_im(s->pc - s->cs_base);
6888
                gen_eob(s);
6889
            } else {
6890
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6891
            }
6892
        } else {
6893
            if (s->iopl == 3) {
6894
                goto gen_sti;
6895
            } else {
6896
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6897
            }
6898
        }
6899
        break;
6900
    case 0x62: /* bound */
6901
        if (CODE64(s))
6902
            goto illegal_op;
6903
        ot = dflag ? OT_LONG : OT_WORD;
6904
        modrm = cpu_ldub_code(env, s->pc++);
6905
        reg = (modrm >> 3) & 7;
6906
        mod = (modrm >> 6) & 3;
6907
        if (mod == 3)
6908
            goto illegal_op;
6909
        gen_op_mov_TN_reg(ot, 0, reg);
6910
        gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
6911
        gen_jmp_im(pc_start - s->cs_base);
6912
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6913
        if (ot == OT_WORD) {
6914
            gen_helper_boundw(cpu_env, cpu_A0, cpu_tmp2_i32);
6915
        } else {
6916
            gen_helper_boundl(cpu_env, cpu_A0, cpu_tmp2_i32);
6917
        }
6918
        break;
6919
    case 0x1c8 ... 0x1cf: /* bswap reg */
6920
        reg = (b & 7) | REX_B(s);
6921
#ifdef TARGET_X86_64
6922
        if (dflag == 2) {
6923
            gen_op_mov_TN_reg(OT_QUAD, 0, reg);
6924
            tcg_gen_bswap64_i64(cpu_T[0], cpu_T[0]);
6925
            gen_op_mov_reg_T0(OT_QUAD, reg);
6926
        } else
6927
#endif
6928
        {
6929
            gen_op_mov_TN_reg(OT_LONG, 0, reg);
6930
            tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
6931
            tcg_gen_bswap32_tl(cpu_T[0], cpu_T[0]);
6932
            gen_op_mov_reg_T0(OT_LONG, reg);
6933
        }
6934
        break;
6935
    case 0xd6: /* salc */
6936
        if (CODE64(s))
6937
            goto illegal_op;
6938
        gen_compute_eflags_c(s, cpu_T[0]);
6939
        tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
6940
        gen_op_mov_reg_T0(OT_BYTE, R_EAX);
6941
        break;
6942
    case 0xe0: /* loopnz */
6943
    case 0xe1: /* loopz */
6944
    case 0xe2: /* loop */
6945
    case 0xe3: /* jecxz */
6946
        {
6947
            int l1, l2, l3;
6948

    
6949
            tval = (int8_t)insn_get(env, s, OT_BYTE);
6950
            next_eip = s->pc - s->cs_base;
6951
            tval += next_eip;
6952
            if (s->dflag == 0)
6953
                tval &= 0xffff;
6954

    
6955
            l1 = gen_new_label();
6956
            l2 = gen_new_label();
6957
            l3 = gen_new_label();
6958
            b &= 3;
6959
            switch(b) {
6960
            case 0: /* loopnz */
6961
            case 1: /* loopz */
6962
                gen_op_add_reg_im(s->aflag, R_ECX, -1);
6963
                gen_op_jz_ecx(s->aflag, l3);
6964
                gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
6965
                break;
6966
            case 2: /* loop */
6967
                gen_op_add_reg_im(s->aflag, R_ECX, -1);
6968
                gen_op_jnz_ecx(s->aflag, l1);
6969
                break;
6970
            default:
6971
            case 3: /* jcxz */
6972
                gen_op_jz_ecx(s->aflag, l1);
6973
                break;
6974
            }
6975

    
6976
            gen_set_label(l3);
6977
            gen_jmp_im(next_eip);
6978
            tcg_gen_br(l2);
6979

    
6980
            gen_set_label(l1);
6981
            gen_jmp_im(tval);
6982
            gen_set_label(l2);
6983
            gen_eob(s);
6984
        }
6985
        break;
6986
    case 0x130: /* wrmsr */
6987
    case 0x132: /* rdmsr */
6988
        if (s->cpl != 0) {
6989
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6990
        } else {
6991
            gen_update_cc_op(s);
6992
            gen_jmp_im(pc_start - s->cs_base);
6993
            if (b & 2) {
6994
                gen_helper_rdmsr(cpu_env);
6995
            } else {
6996
                gen_helper_wrmsr(cpu_env);
6997
            }
6998
        }
6999
        break;
7000
    case 0x131: /* rdtsc */
7001
        gen_update_cc_op(s);
7002
        gen_jmp_im(pc_start - s->cs_base);
7003
        if (use_icount)
7004
            gen_io_start();
7005
        gen_helper_rdtsc(cpu_env);
7006
        if (use_icount) {
7007
            gen_io_end();
7008
            gen_jmp(s, s->pc - s->cs_base);
7009
        }
7010
        break;
7011
    case 0x133: /* rdpmc */
7012
        gen_update_cc_op(s);
7013
        gen_jmp_im(pc_start - s->cs_base);
7014
        gen_helper_rdpmc(cpu_env);
7015
        break;
7016
    case 0x134: /* sysenter */
7017
        /* For Intel SYSENTER is valid on 64-bit */
7018
        if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7019
            goto illegal_op;
7020
        if (!s->pe) {
7021
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7022
        } else {
7023
            gen_update_cc_op(s);
7024
            gen_jmp_im(pc_start - s->cs_base);
7025
            gen_helper_sysenter(cpu_env);
7026
            gen_eob(s);
7027
        }
7028
        break;
7029
    case 0x135: /* sysexit */
7030
        /* For Intel SYSEXIT is valid on 64-bit */
7031
        if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7032
            goto illegal_op;
7033
        if (!s->pe) {
7034
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7035
        } else {
7036
            gen_update_cc_op(s);
7037
            gen_jmp_im(pc_start - s->cs_base);
7038
            gen_helper_sysexit(cpu_env, tcg_const_i32(dflag));
7039
            gen_eob(s);
7040
        }
7041
        break;
7042
#ifdef TARGET_X86_64
7043
    case 0x105: /* syscall */
7044
        /* XXX: is it usable in real mode ? */
7045
        gen_update_cc_op(s);
7046
        gen_jmp_im(pc_start - s->cs_base);
7047
        gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start));
7048
        gen_eob(s);
7049
        break;
7050
    case 0x107: /* sysret */
7051
        if (!s->pe) {
7052
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7053
        } else {
7054
            gen_update_cc_op(s);
7055
            gen_jmp_im(pc_start - s->cs_base);
7056
            gen_helper_sysret(cpu_env, tcg_const_i32(s->dflag));
7057
            /* condition codes are modified only in long mode */
7058
            if (s->lma) {
7059
                set_cc_op(s, CC_OP_EFLAGS);
7060
            }
7061
            gen_eob(s);
7062
        }
7063
        break;
7064
#endif
7065
    case 0x1a2: /* cpuid */
7066
        gen_update_cc_op(s);
7067
        gen_jmp_im(pc_start - s->cs_base);
7068
        gen_helper_cpuid(cpu_env);
7069
        break;
7070
    case 0xf4: /* hlt */
7071
        if (s->cpl != 0) {
7072
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7073
        } else {
7074
            gen_update_cc_op(s);
7075
            gen_jmp_im(pc_start - s->cs_base);
7076
            gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
7077
            s->is_jmp = DISAS_TB_JUMP;
7078
        }
7079
        break;
7080
    case 0x100:
7081
        modrm = cpu_ldub_code(env, s->pc++);
7082
        mod = (modrm >> 6) & 3;
7083
        op = (modrm >> 3) & 7;
7084
        switch(op) {
7085
        case 0: /* sldt */
7086
            if (!s->pe || s->vm86)
7087
                goto illegal_op;
7088
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
7089
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,ldt.selector));
7090
            ot = OT_WORD;
7091
            if (mod == 3)
7092
                ot += s->dflag;
7093
            gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7094
            break;
7095
        case 2: /* lldt */
7096
            if (!s->pe || s->vm86)
7097
                goto illegal_op;
7098
            if (s->cpl != 0) {
7099
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7100
            } else {
7101
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
7102
                gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
7103
                gen_jmp_im(pc_start - s->cs_base);
7104
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
7105
                gen_helper_lldt(cpu_env, cpu_tmp2_i32);
7106
            }
7107
            break;
7108
        case 1: /* str */
7109
            if (!s->pe || s->vm86)
7110
                goto illegal_op;
7111
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
7112
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,tr.selector));
7113
            ot = OT_WORD;
7114
            if (mod == 3)
7115
                ot += s->dflag;
7116
            gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7117
            break;
7118
        case 3: /* ltr */
7119
            if (!s->pe || s->vm86)
7120
                goto illegal_op;
7121
            if (s->cpl != 0) {
7122
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7123
            } else {
7124
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
7125
                gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
7126
                gen_jmp_im(pc_start - s->cs_base);
7127
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
7128
                gen_helper_ltr(cpu_env, cpu_tmp2_i32);
7129
            }
7130
            break;
7131
        case 4: /* verr */
7132
        case 5: /* verw */
7133
            if (!s->pe || s->vm86)
7134
                goto illegal_op;
7135
            gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
7136
            gen_update_cc_op(s);
7137
            if (op == 4) {
7138
                gen_helper_verr(cpu_env, cpu_T[0]);
7139
            } else {
7140
                gen_helper_verw(cpu_env, cpu_T[0]);
7141
            }
7142
            set_cc_op(s, CC_OP_EFLAGS);
7143
            break;
7144
        default:
7145
            goto illegal_op;
7146
        }
7147
        break;
7148
    case 0x101:
7149
        modrm = cpu_ldub_code(env, s->pc++);
7150
        mod = (modrm >> 6) & 3;
7151
        op = (modrm >> 3) & 7;
7152
        rm = modrm & 7;
7153
        switch(op) {
7154
        case 0: /* sgdt */
7155
            if (mod == 3)
7156
                goto illegal_op;
7157
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ);
7158
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7159
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.limit));
7160
            gen_op_st_T0_A0(OT_WORD + s->mem_index);
7161
            gen_add_A0_im(s, 2);
7162
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.base));
7163
            if (!s->dflag)
7164
                gen_op_andl_T0_im(0xffffff);
7165
            gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
7166
            break;
7167
        case 1:
7168
            if (mod == 3) {
7169
                switch (rm) {
7170
                case 0: /* monitor */
7171
                    if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
7172
                        s->cpl != 0)
7173
                        goto illegal_op;
7174
                    gen_update_cc_op(s);
7175
                    gen_jmp_im(pc_start - s->cs_base);
7176
#ifdef TARGET_X86_64
7177
                    if (s->aflag == 2) {
7178
                        gen_op_movq_A0_reg(R_EAX);
7179
                    } else
7180
#endif
7181
                    {
7182
                        gen_op_movl_A0_reg(R_EAX);
7183
                        if (s->aflag == 0)
7184
                            gen_op_andl_A0_ffff();
7185
                    }
7186
                    gen_add_A0_ds_seg(s);
7187
                    gen_helper_monitor(cpu_env, cpu_A0);
7188
                    break;
7189
                case 1: /* mwait */
7190
                    if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
7191
                        s->cpl != 0)
7192
                        goto illegal_op;
7193
                    gen_update_cc_op(s);
7194
                    gen_jmp_im(pc_start - s->cs_base);
7195
                    gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - pc_start));
7196
                    gen_eob(s);
7197
                    break;
7198
                case 2: /* clac */
7199
                    if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) ||
7200
                        s->cpl != 0) {
7201
                        goto illegal_op;
7202
                    }
7203
                    gen_helper_clac(cpu_env);
7204
                    gen_jmp_im(s->pc - s->cs_base);
7205
                    gen_eob(s);
7206
                    break;
7207
                case 3: /* stac */
7208
                    if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) ||
7209
                        s->cpl != 0) {
7210
                        goto illegal_op;
7211
                    }
7212
                    gen_helper_stac(cpu_env);
7213
                    gen_jmp_im(s->pc - s->cs_base);
7214
                    gen_eob(s);
7215
                    break;
7216
                default:
7217
                    goto illegal_op;
7218
                }
7219
            } else { /* sidt */
7220
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ);
7221
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7222
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.limit));
7223
                gen_op_st_T0_A0(OT_WORD + s->mem_index);
7224
                gen_add_A0_im(s, 2);
7225
                tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.base));
7226
                if (!s->dflag)
7227
                    gen_op_andl_T0_im(0xffffff);
7228
                gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
7229
            }
7230
            break;
7231
        case 2: /* lgdt */
7232
        case 3: /* lidt */
7233
            if (mod == 3) {
7234
                gen_update_cc_op(s);
7235
                gen_jmp_im(pc_start - s->cs_base);
7236
                switch(rm) {
7237
                case 0: /* VMRUN */
7238
                    if (!(s->flags & HF_SVME_MASK) || !s->pe)
7239
                        goto illegal_op;
7240
                    if (s->cpl != 0) {
7241
                        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7242
                        break;
7243
                    } else {
7244
                        gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag),
7245
                                         tcg_const_i32(s->pc - pc_start));
7246
                        tcg_gen_exit_tb(0);
7247
                        s->is_jmp = DISAS_TB_JUMP;
7248
                    }
7249
                    break;
7250
                case 1: /* VMMCALL */
7251
                    if (!(s->flags & HF_SVME_MASK))
7252
                        goto illegal_op;
7253
                    gen_helper_vmmcall(cpu_env);
7254
                    break;
7255
                case 2: /* VMLOAD */
7256
                    if (!(s->flags & HF_SVME_MASK) || !s->pe)
7257
                        goto illegal_op;
7258
                    if (s->cpl != 0) {
7259
                        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7260
                        break;
7261
                    } else {
7262
                        gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag));
7263
                    }
7264
                    break;
7265
                case 3: /* VMSAVE */
7266
                    if (!(s->flags & HF_SVME_MASK) || !s->pe)
7267
                        goto illegal_op;
7268
                    if (s->cpl != 0) {
7269
                        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7270
                        break;
7271
                    } else {
7272
                        gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag));
7273
                    }
7274
                    break;
7275
                case 4: /* STGI */
7276
                    if ((!(s->flags & HF_SVME_MASK) &&
7277
                         !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) || 
7278
                        !s->pe)
7279
                        goto illegal_op;
7280
                    if (s->cpl != 0) {
7281
                        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7282
                        break;
7283
                    } else {
7284
                        gen_helper_stgi(cpu_env);
7285
                    }
7286
                    break;
7287
                case 5: /* CLGI */
7288
                    if (!(s->flags & HF_SVME_MASK) || !s->pe)
7289
                        goto illegal_op;
7290
                    if (s->cpl != 0) {
7291
                        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7292
                        break;
7293
                    } else {
7294
                        gen_helper_clgi(cpu_env);
7295
                    }
7296
                    break;
7297
                case 6: /* SKINIT */
7298
                    if ((!(s->flags & HF_SVME_MASK) && 
7299
                         !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) || 
7300
                        !s->pe)
7301
                        goto illegal_op;
7302
                    gen_helper_skinit(cpu_env);
7303
                    break;
7304
                case 7: /* INVLPGA */
7305
                    if (!(s->flags & HF_SVME_MASK) || !s->pe)
7306
                        goto illegal_op;
7307
                    if (s->cpl != 0) {
7308
                        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7309
                        break;
7310
                    } else {
7311
                        gen_helper_invlpga(cpu_env, tcg_const_i32(s->aflag));
7312
                    }
7313
                    break;
7314
                default:
7315
                    goto illegal_op;
7316
                }
7317
            } else if (s->cpl != 0) {
7318
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7319
            } else {
7320
                gen_svm_check_intercept(s, pc_start,
7321
                                        op==2 ? SVM_EXIT_GDTR_WRITE : SVM_EXIT_IDTR_WRITE);
7322
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7323
                gen_op_ld_T1_A0(OT_WORD + s->mem_index);
7324
                gen_add_A0_im(s, 2);
7325
                gen_op_ld_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
7326
                if (!s->dflag)
7327
                    gen_op_andl_T0_im(0xffffff);
7328
                if (op == 2) {
7329
                    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,gdt.base));
7330
                    tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,gdt.limit));
7331
                } else {
7332
                    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,idt.base));
7333
                    tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,idt.limit));
7334
                }
7335
            }
7336
            break;
7337
        case 4: /* smsw */
7338
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
7339
#if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
7340
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]) + 4);
7341
#else
7342
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]));
7343
#endif
7344
            gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 1);
7345
            break;
7346
        case 6: /* lmsw */
7347
            if (s->cpl != 0) {
7348
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7349
            } else {
7350
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7351
                gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
7352
                gen_helper_lmsw(cpu_env, cpu_T[0]);
7353
                gen_jmp_im(s->pc - s->cs_base);
7354
                gen_eob(s);
7355
            }
7356
            break;
7357
        case 7:
7358
            if (mod != 3) { /* invlpg */
7359
                if (s->cpl != 0) {
7360
                    gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7361
                } else {
7362
                    gen_update_cc_op(s);
7363
                    gen_jmp_im(pc_start - s->cs_base);
7364
                    gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7365
                    gen_helper_invlpg(cpu_env, cpu_A0);
7366
                    gen_jmp_im(s->pc - s->cs_base);
7367
                    gen_eob(s);
7368
                }
7369
            } else {
7370
                switch (rm) {
7371
                case 0: /* swapgs */
7372
#ifdef TARGET_X86_64
7373
                    if (CODE64(s)) {
7374
                        if (s->cpl != 0) {
7375
                            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7376
                        } else {
7377
                            tcg_gen_ld_tl(cpu_T[0], cpu_env,
7378
                                offsetof(CPUX86State,segs[R_GS].base));
7379
                            tcg_gen_ld_tl(cpu_T[1], cpu_env,
7380
                                offsetof(CPUX86State,kernelgsbase));
7381
                            tcg_gen_st_tl(cpu_T[1], cpu_env,
7382
                                offsetof(CPUX86State,segs[R_GS].base));
7383
                            tcg_gen_st_tl(cpu_T[0], cpu_env,
7384
                                offsetof(CPUX86State,kernelgsbase));
7385
                        }
7386
                    } else
7387
#endif
7388
                    {
7389
                        goto illegal_op;
7390
                    }
7391
                    break;
7392
                case 1: /* rdtscp */
7393
                    if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP))
7394
                        goto illegal_op;
7395
                    gen_update_cc_op(s);
7396
                    gen_jmp_im(pc_start - s->cs_base);
7397
                    if (use_icount)
7398
                        gen_io_start();
7399
                    gen_helper_rdtscp(cpu_env);
7400
                    if (use_icount) {
7401
                        gen_io_end();
7402
                        gen_jmp(s, s->pc - s->cs_base);
7403
                    }
7404
                    break;
7405
                default:
7406
                    goto illegal_op;
7407
                }
7408
            }
7409
            break;
7410
        default:
7411
            goto illegal_op;
7412
        }
7413
        break;
7414
    case 0x108: /* invd */
7415
    case 0x109: /* wbinvd */
7416
        if (s->cpl != 0) {
7417
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7418
        } else {
7419
            gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
7420
            /* nothing to do */
7421
        }
7422
        break;
7423
    case 0x63: /* arpl or movslS (x86_64) */
7424
#ifdef TARGET_X86_64
7425
        if (CODE64(s)) {
7426
            int d_ot;
7427
            /* d_ot is the size of destination */
7428
            d_ot = dflag + OT_WORD;
7429

    
7430
            modrm = cpu_ldub_code(env, s->pc++);
7431
            reg = ((modrm >> 3) & 7) | rex_r;
7432
            mod = (modrm >> 6) & 3;
7433
            rm = (modrm & 7) | REX_B(s);
7434

    
7435
            if (mod == 3) {
7436
                gen_op_mov_TN_reg(OT_LONG, 0, rm);
7437
                /* sign extend */
7438
                if (d_ot == OT_QUAD)
7439
                    tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
7440
                gen_op_mov_reg_T0(d_ot, reg);
7441
            } else {
7442
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7443
                if (d_ot == OT_QUAD) {
7444
                    gen_op_lds_T0_A0(OT_LONG + s->mem_index);
7445
                } else {
7446
                    gen_op_ld_T0_A0(OT_LONG + s->mem_index);
7447
                }
7448
                gen_op_mov_reg_T0(d_ot, reg);
7449
            }
7450
        } else
7451
#endif
7452
        {
7453
            int label1;
7454
            TCGv t0, t1, t2, a0;
7455

    
7456
            if (!s->pe || s->vm86)
7457
                goto illegal_op;
7458
            t0 = tcg_temp_local_new();
7459
            t1 = tcg_temp_local_new();
7460
            t2 = tcg_temp_local_new();
7461
            ot = OT_WORD;
7462
            modrm = cpu_ldub_code(env, s->pc++);
7463
            reg = (modrm >> 3) & 7;
7464
            mod = (modrm >> 6) & 3;
7465
            rm = modrm & 7;
7466
            if (mod != 3) {
7467
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7468
                gen_op_ld_v(ot + s->mem_index, t0, cpu_A0);
7469
                a0 = tcg_temp_local_new();
7470
                tcg_gen_mov_tl(a0, cpu_A0);
7471
            } else {
7472
                gen_op_mov_v_reg(ot, t0, rm);
7473
                TCGV_UNUSED(a0);
7474
            }
7475
            gen_op_mov_v_reg(ot, t1, reg);
7476
            tcg_gen_andi_tl(cpu_tmp0, t0, 3);
7477
            tcg_gen_andi_tl(t1, t1, 3);
7478
            tcg_gen_movi_tl(t2, 0);
7479
            label1 = gen_new_label();
7480
            tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, t1, label1);
7481
            tcg_gen_andi_tl(t0, t0, ~3);
7482
            tcg_gen_or_tl(t0, t0, t1);
7483
            tcg_gen_movi_tl(t2, CC_Z);
7484
            gen_set_label(label1);
7485
            if (mod != 3) {
7486
                gen_op_st_v(ot + s->mem_index, t0, a0);
7487
                tcg_temp_free(a0);
7488
           } else {
7489
                gen_op_mov_reg_v(ot, rm, t0);
7490
            }
7491
            gen_compute_eflags(s);
7492
            tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
7493
            tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
7494
            tcg_temp_free(t0);
7495
            tcg_temp_free(t1);
7496
            tcg_temp_free(t2);
7497
        }
7498
        break;
7499
    case 0x102: /* lar */
7500
    case 0x103: /* lsl */
7501
        {
7502
            int label1;
7503
            TCGv t0;
7504
            if (!s->pe || s->vm86)
7505
                goto illegal_op;
7506
            ot = dflag ? OT_LONG : OT_WORD;
7507
            modrm = cpu_ldub_code(env, s->pc++);
7508
            reg = ((modrm >> 3) & 7) | rex_r;
7509
            gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
7510
            t0 = tcg_temp_local_new();
7511
            gen_update_cc_op(s);
7512
            if (b == 0x102) {
7513
                gen_helper_lar(t0, cpu_env, cpu_T[0]);
7514
            } else {
7515
                gen_helper_lsl(t0, cpu_env, cpu_T[0]);
7516
            }
7517
            tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
7518
            label1 = gen_new_label();
7519
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
7520
            gen_op_mov_reg_v(ot, reg, t0);
7521
            gen_set_label(label1);
7522
            set_cc_op(s, CC_OP_EFLAGS);
7523
            tcg_temp_free(t0);
7524
        }
7525
        break;
7526
    case 0x118:
7527
        modrm = cpu_ldub_code(env, s->pc++);
7528
        mod = (modrm >> 6) & 3;
7529
        op = (modrm >> 3) & 7;
7530
        switch(op) {
7531
        case 0: /* prefetchnta */
7532
        case 1: /* prefetchnt0 */
7533
        case 2: /* prefetchnt0 */
7534
        case 3: /* prefetchnt0 */
7535
            if (mod == 3)
7536
                goto illegal_op;
7537
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7538
            /* nothing more to do */
7539
            break;
7540
        default: /* nop (multi byte) */
7541
            gen_nop_modrm(env, s, modrm);
7542
            break;
7543
        }
7544
        break;
7545
    case 0x119 ... 0x11f: /* nop (multi byte) */
7546
        modrm = cpu_ldub_code(env, s->pc++);
7547
        gen_nop_modrm(env, s, modrm);
7548
        break;
7549
    case 0x120: /* mov reg, crN */
7550
    case 0x122: /* mov crN, reg */
7551
        if (s->cpl != 0) {
7552
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7553
        } else {
7554
            modrm = cpu_ldub_code(env, s->pc++);
7555
            /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7556
             * AMD documentation (24594.pdf) and testing of
7557
             * intel 386 and 486 processors all show that the mod bits
7558
             * are assumed to be 1's, regardless of actual values.
7559
             */
7560
            rm = (modrm & 7) | REX_B(s);
7561
            reg = ((modrm >> 3) & 7) | rex_r;
7562
            if (CODE64(s))
7563
                ot = OT_QUAD;
7564
            else
7565
                ot = OT_LONG;
7566
            if ((prefixes & PREFIX_LOCK) && (reg == 0) &&
7567
                (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
7568
                reg = 8;
7569
            }
7570
            switch(reg) {
7571
            case 0:
7572
            case 2:
7573
            case 3:
7574
            case 4:
7575
            case 8:
7576
                gen_update_cc_op(s);
7577
                gen_jmp_im(pc_start - s->cs_base);
7578
                if (b & 2) {
7579
                    gen_op_mov_TN_reg(ot, 0, rm);
7580
                    gen_helper_write_crN(cpu_env, tcg_const_i32(reg),
7581
                                         cpu_T[0]);
7582
                    gen_jmp_im(s->pc - s->cs_base);
7583
                    gen_eob(s);
7584
                } else {
7585
                    gen_helper_read_crN(cpu_T[0], cpu_env, tcg_const_i32(reg));
7586
                    gen_op_mov_reg_T0(ot, rm);
7587
                }
7588
                break;
7589
            default:
7590
                goto illegal_op;
7591
            }
7592
        }
7593
        break;
7594
    case 0x121: /* mov reg, drN */
7595
    case 0x123: /* mov drN, reg */
7596
        if (s->cpl != 0) {
7597
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7598
        } else {
7599
            modrm = cpu_ldub_code(env, s->pc++);
7600
            /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7601
             * AMD documentation (24594.pdf) and testing of
7602
             * intel 386 and 486 processors all show that the mod bits
7603
             * are assumed to be 1's, regardless of actual values.
7604
             */
7605
            rm = (modrm & 7) | REX_B(s);
7606
            reg = ((modrm >> 3) & 7) | rex_r;
7607
            if (CODE64(s))
7608
                ot = OT_QUAD;
7609
            else
7610
                ot = OT_LONG;
7611
            /* XXX: do it dynamically with CR4.DE bit */
7612
            if (reg == 4 || reg == 5 || reg >= 8)
7613
                goto illegal_op;
7614
            if (b & 2) {
7615
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
7616
                gen_op_mov_TN_reg(ot, 0, rm);
7617
                gen_helper_movl_drN_T0(cpu_env, tcg_const_i32(reg), cpu_T[0]);
7618
                gen_jmp_im(s->pc - s->cs_base);
7619
                gen_eob(s);
7620
            } else {
7621
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
7622
                tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,dr[reg]));
7623
                gen_op_mov_reg_T0(ot, rm);
7624
            }
7625
        }
7626
        break;
7627
    case 0x106: /* clts */
7628
        if (s->cpl != 0) {
7629
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7630
        } else {
7631
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7632
            gen_helper_clts(cpu_env);
7633
            /* abort block because static cpu state changed */
7634
            gen_jmp_im(s->pc - s->cs_base);
7635
            gen_eob(s);
7636
        }
7637
        break;
7638
    /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7639
    case 0x1c3: /* MOVNTI reg, mem */
7640
        if (!(s->cpuid_features & CPUID_SSE2))
7641
            goto illegal_op;
7642
        ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
7643
        modrm = cpu_ldub_code(env, s->pc++);
7644
        mod = (modrm >> 6) & 3;
7645
        if (mod == 3)
7646
            goto illegal_op;
7647
        reg = ((modrm >> 3) & 7) | rex_r;
7648
        /* generate a generic store */
7649
        gen_ldst_modrm(env, s, modrm, ot, reg, 1);
7650
        break;
7651
    case 0x1ae:
7652
        modrm = cpu_ldub_code(env, s->pc++);
7653
        mod = (modrm >> 6) & 3;
7654
        op = (modrm >> 3) & 7;
7655
        switch(op) {
7656
        case 0: /* fxsave */
7657
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
7658
                (s->prefix & PREFIX_LOCK))
7659
                goto illegal_op;
7660
            if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
7661
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7662
                break;
7663
            }
7664
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7665
            gen_update_cc_op(s);
7666
            gen_jmp_im(pc_start - s->cs_base);
7667
            gen_helper_fxsave(cpu_env, cpu_A0, tcg_const_i32((s->dflag == 2)));
7668
            break;
7669
        case 1: /* fxrstor */
7670
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
7671
                (s->prefix & PREFIX_LOCK))
7672
                goto illegal_op;
7673
            if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
7674
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7675
                break;
7676
            }
7677
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7678
            gen_update_cc_op(s);
7679
            gen_jmp_im(pc_start - s->cs_base);
7680
            gen_helper_fxrstor(cpu_env, cpu_A0,
7681
                               tcg_const_i32((s->dflag == 2)));
7682
            break;
7683
        case 2: /* ldmxcsr */
7684
        case 3: /* stmxcsr */
7685
            if (s->flags & HF_TS_MASK) {
7686
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7687
                break;
7688
            }
7689
            if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
7690
                mod == 3)
7691
                goto illegal_op;
7692
            gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7693
            if (op == 2) {
7694
                gen_op_ld_T0_A0(OT_LONG + s->mem_index);
7695
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
7696
                gen_helper_ldmxcsr(cpu_env, cpu_tmp2_i32);
7697
            } else {
7698
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
7699
                gen_op_st_T0_A0(OT_LONG + s->mem_index);
7700
            }
7701
            break;
7702
        case 5: /* lfence */
7703
        case 6: /* mfence */
7704
            if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE2))
7705
                goto illegal_op;
7706
            break;
7707
        case 7: /* sfence / clflush */
7708
            if ((modrm & 0xc7) == 0xc0) {
7709
                /* sfence */
7710
                /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
7711
                if (!(s->cpuid_features & CPUID_SSE))
7712
                    goto illegal_op;
7713
            } else {
7714
                /* clflush */
7715
                if (!(s->cpuid_features & CPUID_CLFLUSH))
7716
                    goto illegal_op;
7717
                gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7718
            }
7719
            break;
7720
        default:
7721
            goto illegal_op;
7722
        }
7723
        break;
7724
    case 0x10d: /* 3DNow! prefetch(w) */
7725
        modrm = cpu_ldub_code(env, s->pc++);
7726
        mod = (modrm >> 6) & 3;
7727
        if (mod == 3)
7728
            goto illegal_op;
7729
        gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7730
        /* ignore for now */
7731
        break;
7732
    case 0x1aa: /* rsm */
7733
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
7734
        if (!(s->flags & HF_SMM_MASK))
7735
            goto illegal_op;
7736
        gen_update_cc_op(s);
7737
        gen_jmp_im(s->pc - s->cs_base);
7738
        gen_helper_rsm(cpu_env);
7739
        gen_eob(s);
7740
        break;
7741
    case 0x1b8: /* SSE4.2 popcnt */
7742
        if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
7743
             PREFIX_REPZ)
7744
            goto illegal_op;
7745
        if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
7746
            goto illegal_op;
7747

    
7748
        modrm = cpu_ldub_code(env, s->pc++);
7749
        reg = ((modrm >> 3) & 7) | rex_r;
7750

    
7751
        if (s->prefix & PREFIX_DATA)
7752
            ot = OT_WORD;
7753
        else if (s->dflag != 2)
7754
            ot = OT_LONG;
7755
        else
7756
            ot = OT_QUAD;
7757

    
7758
        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
7759
        gen_helper_popcnt(cpu_T[0], cpu_env, cpu_T[0], tcg_const_i32(ot));
7760
        gen_op_mov_reg_T0(ot, reg);
7761

    
7762
        set_cc_op(s, CC_OP_EFLAGS);
7763
        break;
7764
    case 0x10e ... 0x10f:
7765
        /* 3DNow! instructions, ignore prefixes */
7766
        s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
7767
    case 0x110 ... 0x117:
7768
    case 0x128 ... 0x12f:
7769
    case 0x138 ... 0x13a:
7770
    case 0x150 ... 0x179:
7771
    case 0x17c ... 0x17f:
7772
    case 0x1c2:
7773
    case 0x1c4 ... 0x1c6:
7774
    case 0x1d0 ... 0x1fe:
7775
        gen_sse(env, s, b, pc_start, rex_r);
7776
        break;
7777
    default:
7778
        goto illegal_op;
7779
    }
7780
    /* lock generation */
7781
    if (s->prefix & PREFIX_LOCK)
7782
        gen_helper_unlock();
7783
    return s->pc;
7784
 illegal_op:
7785
    if (s->prefix & PREFIX_LOCK)
7786
        gen_helper_unlock();
7787
    /* XXX: ensure that no lock was generated */
7788
    gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
7789
    return s->pc;
7790
}
7791

    
7792
void optimize_flags_init(void)
7793
{
7794
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
7795
    cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0,
7796
                                       offsetof(CPUX86State, cc_op), "cc_op");
7797
    cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_dst),
7798
                                    "cc_dst");
7799
    cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_src),
7800
                                    "cc_src");
7801
    cpu_cc_src2 = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_src2),
7802
                                     "cc_src2");
7803

    
7804
#ifdef TARGET_X86_64
7805
    cpu_regs[R_EAX] = tcg_global_mem_new_i64(TCG_AREG0,
7806
                                             offsetof(CPUX86State, regs[R_EAX]), "rax");
7807
    cpu_regs[R_ECX] = tcg_global_mem_new_i64(TCG_AREG0,
7808
                                             offsetof(CPUX86State, regs[R_ECX]), "rcx");
7809
    cpu_regs[R_EDX] = tcg_global_mem_new_i64(TCG_AREG0,
7810
                                             offsetof(CPUX86State, regs[R_EDX]), "rdx");
7811
    cpu_regs[R_EBX] = tcg_global_mem_new_i64(TCG_AREG0,
7812
                                             offsetof(CPUX86State, regs[R_EBX]), "rbx");
7813
    cpu_regs[R_ESP] = tcg_global_mem_new_i64(TCG_AREG0,
7814
                                             offsetof(CPUX86State, regs[R_ESP]), "rsp");
7815
    cpu_regs[R_EBP] = tcg_global_mem_new_i64(TCG_AREG0,
7816
                                             offsetof(CPUX86State, regs[R_EBP]), "rbp");
7817
    cpu_regs[R_ESI] = tcg_global_mem_new_i64(TCG_AREG0,
7818
                                             offsetof(CPUX86State, regs[R_ESI]), "rsi");
7819
    cpu_regs[R_EDI] = tcg_global_mem_new_i64(TCG_AREG0,
7820
                                             offsetof(CPUX86State, regs[R_EDI]), "rdi");
7821
    cpu_regs[8] = tcg_global_mem_new_i64(TCG_AREG0,
7822
                                         offsetof(CPUX86State, regs[8]), "r8");
7823
    cpu_regs[9] = tcg_global_mem_new_i64(TCG_AREG0,
7824
                                          offsetof(CPUX86State, regs[9]), "r9");
7825
    cpu_regs[10] = tcg_global_mem_new_i64(TCG_AREG0,
7826
                                          offsetof(CPUX86State, regs[10]), "r10");
7827
    cpu_regs[11] = tcg_global_mem_new_i64(TCG_AREG0,
7828
                                          offsetof(CPUX86State, regs[11]), "r11");
7829
    cpu_regs[12] = tcg_global_mem_new_i64(TCG_AREG0,
7830
                                          offsetof(CPUX86State, regs[12]), "r12");
7831
    cpu_regs[13] = tcg_global_mem_new_i64(TCG_AREG0,
7832
                                          offsetof(CPUX86State, regs[13]), "r13");
7833
    cpu_regs[14] = tcg_global_mem_new_i64(TCG_AREG0,
7834
                                          offsetof(CPUX86State, regs[14]), "r14");
7835
    cpu_regs[15] = tcg_global_mem_new_i64(TCG_AREG0,
7836
                                          offsetof(CPUX86State, regs[15]), "r15");
7837
#else
7838
    cpu_regs[R_EAX] = tcg_global_mem_new_i32(TCG_AREG0,
7839
                                             offsetof(CPUX86State, regs[R_EAX]), "eax");
7840
    cpu_regs[R_ECX] = tcg_global_mem_new_i32(TCG_AREG0,
7841
                                             offsetof(CPUX86State, regs[R_ECX]), "ecx");
7842
    cpu_regs[R_EDX] = tcg_global_mem_new_i32(TCG_AREG0,
7843
                                             offsetof(CPUX86State, regs[R_EDX]), "edx");
7844
    cpu_regs[R_EBX] = tcg_global_mem_new_i32(TCG_AREG0,
7845
                                             offsetof(CPUX86State, regs[R_EBX]), "ebx");
7846
    cpu_regs[R_ESP] = tcg_global_mem_new_i32(TCG_AREG0,
7847
                                             offsetof(CPUX86State, regs[R_ESP]), "esp");
7848
    cpu_regs[R_EBP] = tcg_global_mem_new_i32(TCG_AREG0,
7849
                                             offsetof(CPUX86State, regs[R_EBP]), "ebp");
7850
    cpu_regs[R_ESI] = tcg_global_mem_new_i32(TCG_AREG0,
7851
                                             offsetof(CPUX86State, regs[R_ESI]), "esi");
7852
    cpu_regs[R_EDI] = tcg_global_mem_new_i32(TCG_AREG0,
7853
                                             offsetof(CPUX86State, regs[R_EDI]), "edi");
7854
#endif
7855

    
7856
    /* register helpers */
7857
#define GEN_HELPER 2
7858
#include "helper.h"
7859
}
7860

    
7861
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
7862
   basic block 'tb'. If search_pc is TRUE, also generate PC
7863
   information for each intermediate instruction. */
7864
static inline void gen_intermediate_code_internal(CPUX86State *env,
7865
                                                  TranslationBlock *tb,
7866
                                                  int search_pc)
7867
{
7868
    DisasContext dc1, *dc = &dc1;
7869
    target_ulong pc_ptr;
7870
    uint16_t *gen_opc_end;
7871
    CPUBreakpoint *bp;
7872
    int j, lj;
7873
    uint64_t flags;
7874
    target_ulong pc_start;
7875
    target_ulong cs_base;
7876
    int num_insns;
7877
    int max_insns;
7878

    
7879
    /* generate intermediate code */
7880
    pc_start = tb->pc;
7881
    cs_base = tb->cs_base;
7882
    flags = tb->flags;
7883

    
7884
    dc->pe = (flags >> HF_PE_SHIFT) & 1;
7885
    dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
7886
    dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
7887
    dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
7888
    dc->f_st = 0;
7889
    dc->vm86 = (flags >> VM_SHIFT) & 1;
7890
    dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
7891
    dc->iopl = (flags >> IOPL_SHIFT) & 3;
7892
    dc->tf = (flags >> TF_SHIFT) & 1;
7893
    dc->singlestep_enabled = env->singlestep_enabled;
7894
    dc->cc_op = CC_OP_DYNAMIC;
7895
    dc->cc_op_dirty = false;
7896
    dc->cs_base = cs_base;
7897
    dc->tb = tb;
7898
    dc->popl_esp_hack = 0;
7899
    /* select memory access functions */
7900
    dc->mem_index = 0;
7901
    if (flags & HF_SOFTMMU_MASK) {
7902
        dc->mem_index = (cpu_mmu_index(env) + 1) << 2;
7903
    }
7904
    dc->cpuid_features = env->cpuid_features;
7905
    dc->cpuid_ext_features = env->cpuid_ext_features;
7906
    dc->cpuid_ext2_features = env->cpuid_ext2_features;
7907
    dc->cpuid_ext3_features = env->cpuid_ext3_features;
7908
    dc->cpuid_7_0_ebx_features = env->cpuid_7_0_ebx_features;
7909
#ifdef TARGET_X86_64
7910
    dc->lma = (flags >> HF_LMA_SHIFT) & 1;
7911
    dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
7912
#endif
7913
    dc->flags = flags;
7914
    dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
7915
                    (flags & HF_INHIBIT_IRQ_MASK)
7916
#ifndef CONFIG_SOFTMMU
7917
                    || (flags & HF_SOFTMMU_MASK)
7918
#endif
7919
                    );
7920
#if 0
7921
    /* check addseg logic */
7922
    if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
7923
        printf("ERROR addseg\n");
7924
#endif
7925

    
7926
    cpu_T[0] = tcg_temp_new();
7927
    cpu_T[1] = tcg_temp_new();
7928
    cpu_A0 = tcg_temp_new();
7929

    
7930
    cpu_tmp0 = tcg_temp_new();
7931
    cpu_tmp1_i64 = tcg_temp_new_i64();
7932
    cpu_tmp2_i32 = tcg_temp_new_i32();
7933
    cpu_tmp3_i32 = tcg_temp_new_i32();
7934
    cpu_tmp4 = tcg_temp_new();
7935
    cpu_tmp5 = tcg_temp_new();
7936
    cpu_ptr0 = tcg_temp_new_ptr();
7937
    cpu_ptr1 = tcg_temp_new_ptr();
7938
    cpu_cc_srcT = tcg_temp_local_new();
7939

    
7940
    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
7941

    
7942
    dc->is_jmp = DISAS_NEXT;
7943
    pc_ptr = pc_start;
7944
    lj = -1;
7945
    num_insns = 0;
7946
    max_insns = tb->cflags & CF_COUNT_MASK;
7947
    if (max_insns == 0)
7948
        max_insns = CF_COUNT_MASK;
7949

    
7950
    gen_icount_start();
7951
    for(;;) {
7952
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
7953
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
7954
                if (bp->pc == pc_ptr &&
7955
                    !((bp->flags & BP_CPU) && (tb->flags & HF_RF_MASK))) {
7956
                    gen_debug(dc, pc_ptr - dc->cs_base);
7957
                    break;
7958
                }
7959
            }
7960
        }
7961
        if (search_pc) {
7962
            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
7963
            if (lj < j) {
7964
                lj++;
7965
                while (lj < j)
7966
                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
7967
            }
7968
            tcg_ctx.gen_opc_pc[lj] = pc_ptr;
7969
            gen_opc_cc_op[lj] = dc->cc_op;
7970
            tcg_ctx.gen_opc_instr_start[lj] = 1;
7971
            tcg_ctx.gen_opc_icount[lj] = num_insns;
7972
        }
7973
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
7974
            gen_io_start();
7975

    
7976
        pc_ptr = disas_insn(env, dc, pc_ptr);
7977
        num_insns++;
7978
        /* stop translation if indicated */
7979
        if (dc->is_jmp)
7980
            break;
7981
        /* if single step mode, we generate only one instruction and
7982
           generate an exception */
7983
        /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
7984
           the flag and abort the translation to give the irqs a
7985
           change to be happen */
7986
        if (dc->tf || dc->singlestep_enabled ||
7987
            (flags & HF_INHIBIT_IRQ_MASK)) {
7988
            gen_jmp_im(pc_ptr - dc->cs_base);
7989
            gen_eob(dc);
7990
            break;
7991
        }
7992
        /* if too long translation, stop generation too */
7993
        if (tcg_ctx.gen_opc_ptr >= gen_opc_end ||
7994
            (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32) ||
7995
            num_insns >= max_insns) {
7996
            gen_jmp_im(pc_ptr - dc->cs_base);
7997
            gen_eob(dc);
7998
            break;
7999
        }
8000
        if (singlestep) {
8001
            gen_jmp_im(pc_ptr - dc->cs_base);
8002
            gen_eob(dc);
8003
            break;
8004
        }
8005
    }
8006
    if (tb->cflags & CF_LAST_IO)
8007
        gen_io_end();
8008
    gen_icount_end(tb, num_insns);
8009
    *tcg_ctx.gen_opc_ptr = INDEX_op_end;
8010
    /* we don't forget to fill the last values */
8011
    if (search_pc) {
8012
        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
8013
        lj++;
8014
        while (lj <= j)
8015
            tcg_ctx.gen_opc_instr_start[lj++] = 0;
8016
    }
8017

    
8018
#ifdef DEBUG_DISAS
8019
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8020
        int disas_flags;
8021
        qemu_log("----------------\n");
8022
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
8023
#ifdef TARGET_X86_64
8024
        if (dc->code64)
8025
            disas_flags = 2;
8026
        else
8027
#endif
8028
            disas_flags = !dc->code32;
8029
        log_target_disas(env, pc_start, pc_ptr - pc_start, disas_flags);
8030
        qemu_log("\n");
8031
    }
8032
#endif
8033

    
8034
    if (!search_pc) {
8035
        tb->size = pc_ptr - pc_start;
8036
        tb->icount = num_insns;
8037
    }
8038
}
8039

    
8040
void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
8041
{
8042
    gen_intermediate_code_internal(env, tb, 0);
8043
}
8044

    
8045
void gen_intermediate_code_pc(CPUX86State *env, TranslationBlock *tb)
8046
{
8047
    gen_intermediate_code_internal(env, tb, 1);
8048
}
8049

    
8050
void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, int pc_pos)
8051
{
8052
    int cc_op;
8053
#ifdef DEBUG_DISAS
8054
    if (qemu_loglevel_mask(CPU_LOG_TB_OP)) {
8055
        int i;
8056
        qemu_log("RESTORE:\n");
8057
        for(i = 0;i <= pc_pos; i++) {
8058
            if (tcg_ctx.gen_opc_instr_start[i]) {
8059
                qemu_log("0x%04x: " TARGET_FMT_lx "\n", i,
8060
                        tcg_ctx.gen_opc_pc[i]);
8061
            }
8062
        }
8063
        qemu_log("pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
8064
                pc_pos, tcg_ctx.gen_opc_pc[pc_pos] - tb->cs_base,
8065
                (uint32_t)tb->cs_base);
8066
    }
8067
#endif
8068
    env->eip = tcg_ctx.gen_opc_pc[pc_pos] - tb->cs_base;
8069
    cc_op = gen_opc_cc_op[pc_pos];
8070
    if (cc_op != CC_OP_DYNAMIC)
8071
        env->cc_op = cc_op;
8072
}