Statistics
| Branch: | Revision:

root / target-i386 / translate.c @ 5b207c00

History | View | Annotate | Download (251.3 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 "cpu.h"
27
#include "exec-all.h"
28
#include "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

    
41
#ifdef TARGET_X86_64
42
#define X86_64_ONLY(x) x
43
#define X86_64_DEF(...)  __VA_ARGS__
44
#define CODE64(s) ((s)->code64)
45
#define REX_X(s) ((s)->rex_x)
46
#define REX_B(s) ((s)->rex_b)
47
/* XXX: gcc generates push/pop in some opcodes, so we cannot use them */
48
#if 1
49
#define BUGGY_64(x) NULL
50
#endif
51
#else
52
#define X86_64_ONLY(x) NULL
53
#define X86_64_DEF(...)
54
#define CODE64(s) 0
55
#define REX_X(s) 0
56
#define REX_B(s) 0
57
#endif
58

    
59
//#define MACRO_TEST   1
60

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

    
74
#include "gen-icount.h"
75

    
76
#ifdef TARGET_X86_64
77
static int x86_64_hregs;
78
#endif
79

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

    
118
static void gen_eob(DisasContext *s);
119
static void gen_jmp(DisasContext *s, target_ulong eip);
120
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
121

    
122
/* i386 arith/logic operations */
123
enum {
124
    OP_ADDL,
125
    OP_ORL,
126
    OP_ADCL,
127
    OP_SBBL,
128
    OP_ANDL,
129
    OP_SUBL,
130
    OP_XORL,
131
    OP_CMPL,
132
};
133

    
134
/* i386 shift ops */
135
enum {
136
    OP_ROL,
137
    OP_ROR,
138
    OP_RCL,
139
    OP_RCR,
140
    OP_SHL,
141
    OP_SHR,
142
    OP_SHL1, /* undocumented */
143
    OP_SAR = 7,
144
};
145

    
146
enum {
147
    JCC_O,
148
    JCC_B,
149
    JCC_Z,
150
    JCC_BE,
151
    JCC_S,
152
    JCC_P,
153
    JCC_L,
154
    JCC_LE,
155
};
156

    
157
/* operand size */
158
enum {
159
    OT_BYTE = 0,
160
    OT_WORD,
161
    OT_LONG,
162
    OT_QUAD,
163
};
164

    
165
enum {
166
    /* I386 int registers */
167
    OR_EAX,   /* MUST be even numbered */
168
    OR_ECX,
169
    OR_EDX,
170
    OR_EBX,
171
    OR_ESP,
172
    OR_EBP,
173
    OR_ESI,
174
    OR_EDI,
175

    
176
    OR_TMP0 = 16,    /* temporary operand register */
177
    OR_TMP1,
178
    OR_A0, /* temporary register used when doing address evaluation */
179
};
180

    
181
static inline void gen_op_movl_T0_0(void)
182
{
183
    tcg_gen_movi_tl(cpu_T[0], 0);
184
}
185

    
186
static inline void gen_op_movl_T0_im(int32_t val)
187
{
188
    tcg_gen_movi_tl(cpu_T[0], val);
189
}
190

    
191
static inline void gen_op_movl_T0_imu(uint32_t val)
192
{
193
    tcg_gen_movi_tl(cpu_T[0], val);
194
}
195

    
196
static inline void gen_op_movl_T1_im(int32_t val)
197
{
198
    tcg_gen_movi_tl(cpu_T[1], val);
199
}
200

    
201
static inline void gen_op_movl_T1_imu(uint32_t val)
202
{
203
    tcg_gen_movi_tl(cpu_T[1], val);
204
}
205

    
206
static inline void gen_op_movl_A0_im(uint32_t val)
207
{
208
    tcg_gen_movi_tl(cpu_A0, val);
209
}
210

    
211
#ifdef TARGET_X86_64
212
static inline void gen_op_movq_A0_im(int64_t val)
213
{
214
    tcg_gen_movi_tl(cpu_A0, val);
215
}
216
#endif
217

    
218
static inline void gen_movtl_T0_im(target_ulong val)
219
{
220
    tcg_gen_movi_tl(cpu_T[0], val);
221
}
222

    
223
static inline void gen_movtl_T1_im(target_ulong val)
224
{
225
    tcg_gen_movi_tl(cpu_T[1], val);
226
}
227

    
228
static inline void gen_op_andl_T0_ffff(void)
229
{
230
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
231
}
232

    
233
static inline void gen_op_andl_T0_im(uint32_t val)
234
{
235
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], val);
236
}
237

    
238
static inline void gen_op_movl_T0_T1(void)
239
{
240
    tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
241
}
242

    
243
static inline void gen_op_andl_A0_ffff(void)
244
{
245
    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffff);
246
}
247

    
248
#ifdef TARGET_X86_64
249

    
250
#define NB_OP_SIZES 4
251

    
252
#else /* !TARGET_X86_64 */
253

    
254
#define NB_OP_SIZES 3
255

    
256
#endif /* !TARGET_X86_64 */
257

    
258
#if defined(HOST_WORDS_BIGENDIAN)
259
#define REG_B_OFFSET (sizeof(target_ulong) - 1)
260
#define REG_H_OFFSET (sizeof(target_ulong) - 2)
261
#define REG_W_OFFSET (sizeof(target_ulong) - 2)
262
#define REG_L_OFFSET (sizeof(target_ulong) - 4)
263
#define REG_LH_OFFSET (sizeof(target_ulong) - 8)
264
#else
265
#define REG_B_OFFSET 0
266
#define REG_H_OFFSET 1
267
#define REG_W_OFFSET 0
268
#define REG_L_OFFSET 0
269
#define REG_LH_OFFSET 4
270
#endif
271

    
272
static inline void gen_op_mov_reg_v(int ot, int reg, TCGv t0)
273
{
274
    switch(ot) {
275
    case OT_BYTE:
276
        if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
277
            tcg_gen_st8_tl(t0, cpu_env, offsetof(CPUState, regs[reg]) + REG_B_OFFSET);
278
        } else {
279
            tcg_gen_st8_tl(t0, cpu_env, offsetof(CPUState, regs[reg - 4]) + REG_H_OFFSET);
280
        }
281
        break;
282
    case OT_WORD:
283
        tcg_gen_st16_tl(t0, cpu_env, offsetof(CPUState, regs[reg]) + REG_W_OFFSET);
284
        break;
285
#ifdef TARGET_X86_64
286
    case OT_LONG:
287
        tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
288
        /* high part of register set to zero */
289
        tcg_gen_movi_tl(cpu_tmp0, 0);
290
        tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_LH_OFFSET);
291
        break;
292
    default:
293
    case OT_QUAD:
294
        tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, regs[reg]));
295
        break;
296
#else
297
    default:
298
    case OT_LONG:
299
        tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
300
        break;
301
#endif
302
    }
303
}
304

    
305
static inline void gen_op_mov_reg_T0(int ot, int reg)
306
{
307
    gen_op_mov_reg_v(ot, reg, cpu_T[0]);
308
}
309

    
310
static inline void gen_op_mov_reg_T1(int ot, int reg)
311
{
312
    gen_op_mov_reg_v(ot, reg, cpu_T[1]);
313
}
314

    
315
static inline void gen_op_mov_reg_A0(int size, int reg)
316
{
317
    switch(size) {
318
    case 0:
319
        tcg_gen_st16_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]) + REG_W_OFFSET);
320
        break;
321
#ifdef TARGET_X86_64
322
    case 1:
323
        tcg_gen_st32_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
324
        /* high part of register set to zero */
325
        tcg_gen_movi_tl(cpu_tmp0, 0);
326
        tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_LH_OFFSET);
327
        break;
328
    default:
329
    case 2:
330
        tcg_gen_st_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]));
331
        break;
332
#else
333
    default:
334
    case 1:
335
        tcg_gen_st32_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
336
        break;
337
#endif
338
    }
339
}
340

    
341
static inline void gen_op_mov_v_reg(int ot, TCGv t0, int reg)
342
{
343
    switch(ot) {
344
    case OT_BYTE:
345
        if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
346
            goto std_case;
347
        } else {
348
            tcg_gen_ld8u_tl(t0, cpu_env, offsetof(CPUState, regs[reg - 4]) + REG_H_OFFSET);
349
        }
350
        break;
351
    default:
352
    std_case:
353
        tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, regs[reg]));
354
        break;
355
    }
356
}
357

    
358
static inline void gen_op_mov_TN_reg(int ot, int t_index, int reg)
359
{
360
    gen_op_mov_v_reg(ot, cpu_T[t_index], reg);
361
}
362

    
363
static inline void gen_op_movl_A0_reg(int reg)
364
{
365
    tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
366
}
367

    
368
static inline void gen_op_addl_A0_im(int32_t val)
369
{
370
    tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
371
#ifdef TARGET_X86_64
372
    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
373
#endif
374
}
375

    
376
#ifdef TARGET_X86_64
377
static inline void gen_op_addq_A0_im(int64_t val)
378
{
379
    tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
380
}
381
#endif
382
    
383
static void gen_add_A0_im(DisasContext *s, int val)
384
{
385
#ifdef TARGET_X86_64
386
    if (CODE64(s))
387
        gen_op_addq_A0_im(val);
388
    else
389
#endif
390
        gen_op_addl_A0_im(val);
391
}
392

    
393
static inline void gen_op_addl_T0_T1(void)
394
{
395
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
396
}
397

    
398
static inline void gen_op_jmp_T0(void)
399
{
400
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, eip));
401
}
402

    
403
static inline void gen_op_add_reg_im(int size, int reg, int32_t val)
404
{
405
    switch(size) {
406
    case 0:
407
        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
408
        tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val);
409
        tcg_gen_st16_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_W_OFFSET);
410
        break;
411
    case 1:
412
        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
413
        tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val);
414
#ifdef TARGET_X86_64
415
        tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff);
416
#endif
417
        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
418
        break;
419
#ifdef TARGET_X86_64
420
    case 2:
421
        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
422
        tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val);
423
        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
424
        break;
425
#endif
426
    }
427
}
428

    
429
static inline void gen_op_add_reg_T0(int size, int reg)
430
{
431
    switch(size) {
432
    case 0:
433
        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
434
        tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]);
435
        tcg_gen_st16_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_W_OFFSET);
436
        break;
437
    case 1:
438
        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
439
        tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]);
440
#ifdef TARGET_X86_64
441
        tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff);
442
#endif
443
        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
444
        break;
445
#ifdef TARGET_X86_64
446
    case 2:
447
        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
448
        tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]);
449
        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
450
        break;
451
#endif
452
    }
453
}
454

    
455
static inline void gen_op_set_cc_op(int32_t val)
456
{
457
    tcg_gen_movi_i32(cpu_cc_op, val);
458
}
459

    
460
static inline void gen_op_addl_A0_reg_sN(int shift, int reg)
461
{
462
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
463
    if (shift != 0) 
464
        tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
465
    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
466
#ifdef TARGET_X86_64
467
    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
468
#endif
469
}
470

    
471
static inline void gen_op_movl_A0_seg(int reg)
472
{
473
    tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUState, segs[reg].base) + REG_L_OFFSET);
474
}
475

    
476
static inline void gen_op_addl_A0_seg(int reg)
477
{
478
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, segs[reg].base));
479
    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
480
#ifdef TARGET_X86_64
481
    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
482
#endif
483
}
484

    
485
#ifdef TARGET_X86_64
486
static inline void gen_op_movq_A0_seg(int reg)
487
{
488
    tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUState, segs[reg].base));
489
}
490

    
491
static inline void gen_op_addq_A0_seg(int reg)
492
{
493
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, segs[reg].base));
494
    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
495
}
496

    
497
static inline void gen_op_movq_A0_reg(int reg)
498
{
499
    tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]));
500
}
501

    
502
static inline void gen_op_addq_A0_reg_sN(int shift, int reg)
503
{
504
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
505
    if (shift != 0) 
506
        tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
507
    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
508
}
509
#endif
510

    
511
static inline void gen_op_lds_T0_A0(int idx)
512
{
513
    int mem_index = (idx >> 2) - 1;
514
    switch(idx & 3) {
515
    case 0:
516
        tcg_gen_qemu_ld8s(cpu_T[0], cpu_A0, mem_index);
517
        break;
518
    case 1:
519
        tcg_gen_qemu_ld16s(cpu_T[0], cpu_A0, mem_index);
520
        break;
521
    default:
522
    case 2:
523
        tcg_gen_qemu_ld32s(cpu_T[0], cpu_A0, mem_index);
524
        break;
525
    }
526
}
527

    
528
static inline void gen_op_ld_v(int idx, TCGv t0, TCGv a0)
529
{
530
    int mem_index = (idx >> 2) - 1;
531
    switch(idx & 3) {
532
    case 0:
533
        tcg_gen_qemu_ld8u(t0, a0, mem_index);
534
        break;
535
    case 1:
536
        tcg_gen_qemu_ld16u(t0, a0, mem_index);
537
        break;
538
    case 2:
539
        tcg_gen_qemu_ld32u(t0, a0, mem_index);
540
        break;
541
    default:
542
    case 3:
543
        /* Should never happen on 32-bit targets.  */
544
#ifdef TARGET_X86_64
545
        tcg_gen_qemu_ld64(t0, a0, mem_index);
546
#endif
547
        break;
548
    }
549
}
550

    
551
/* XXX: always use ldu or lds */
552
static inline void gen_op_ld_T0_A0(int idx)
553
{
554
    gen_op_ld_v(idx, cpu_T[0], cpu_A0);
555
}
556

    
557
static inline void gen_op_ldu_T0_A0(int idx)
558
{
559
    gen_op_ld_v(idx, cpu_T[0], cpu_A0);
560
}
561

    
562
static inline void gen_op_ld_T1_A0(int idx)
563
{
564
    gen_op_ld_v(idx, cpu_T[1], cpu_A0);
565
}
566

    
567
static inline void gen_op_st_v(int idx, TCGv t0, TCGv a0)
568
{
569
    int mem_index = (idx >> 2) - 1;
570
    switch(idx & 3) {
571
    case 0:
572
        tcg_gen_qemu_st8(t0, a0, mem_index);
573
        break;
574
    case 1:
575
        tcg_gen_qemu_st16(t0, a0, mem_index);
576
        break;
577
    case 2:
578
        tcg_gen_qemu_st32(t0, a0, mem_index);
579
        break;
580
    default:
581
    case 3:
582
        /* Should never happen on 32-bit targets.  */
583
#ifdef TARGET_X86_64
584
        tcg_gen_qemu_st64(t0, a0, mem_index);
585
#endif
586
        break;
587
    }
588
}
589

    
590
static inline void gen_op_st_T0_A0(int idx)
591
{
592
    gen_op_st_v(idx, cpu_T[0], cpu_A0);
593
}
594

    
595
static inline void gen_op_st_T1_A0(int idx)
596
{
597
    gen_op_st_v(idx, cpu_T[1], cpu_A0);
598
}
599

    
600
static inline void gen_jmp_im(target_ulong pc)
601
{
602
    tcg_gen_movi_tl(cpu_tmp0, pc);
603
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, eip));
604
}
605

    
606
static inline void gen_string_movl_A0_ESI(DisasContext *s)
607
{
608
    int override;
609

    
610
    override = s->override;
611
#ifdef TARGET_X86_64
612
    if (s->aflag == 2) {
613
        if (override >= 0) {
614
            gen_op_movq_A0_seg(override);
615
            gen_op_addq_A0_reg_sN(0, R_ESI);
616
        } else {
617
            gen_op_movq_A0_reg(R_ESI);
618
        }
619
    } else
620
#endif
621
    if (s->aflag) {
622
        /* 32 bit address */
623
        if (s->addseg && override < 0)
624
            override = R_DS;
625
        if (override >= 0) {
626
            gen_op_movl_A0_seg(override);
627
            gen_op_addl_A0_reg_sN(0, R_ESI);
628
        } else {
629
            gen_op_movl_A0_reg(R_ESI);
630
        }
631
    } else {
632
        /* 16 address, always override */
633
        if (override < 0)
634
            override = R_DS;
635
        gen_op_movl_A0_reg(R_ESI);
636
        gen_op_andl_A0_ffff();
637
        gen_op_addl_A0_seg(override);
638
    }
639
}
640

    
641
static inline void gen_string_movl_A0_EDI(DisasContext *s)
642
{
643
#ifdef TARGET_X86_64
644
    if (s->aflag == 2) {
645
        gen_op_movq_A0_reg(R_EDI);
646
    } else
647
#endif
648
    if (s->aflag) {
649
        if (s->addseg) {
650
            gen_op_movl_A0_seg(R_ES);
651
            gen_op_addl_A0_reg_sN(0, R_EDI);
652
        } else {
653
            gen_op_movl_A0_reg(R_EDI);
654
        }
655
    } else {
656
        gen_op_movl_A0_reg(R_EDI);
657
        gen_op_andl_A0_ffff();
658
        gen_op_addl_A0_seg(R_ES);
659
    }
660
}
661

    
662
static inline void gen_op_movl_T0_Dshift(int ot) 
663
{
664
    tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUState, df));
665
    tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot);
666
};
667

    
668
static void gen_extu(int ot, TCGv reg)
669
{
670
    switch(ot) {
671
    case OT_BYTE:
672
        tcg_gen_ext8u_tl(reg, reg);
673
        break;
674
    case OT_WORD:
675
        tcg_gen_ext16u_tl(reg, reg);
676
        break;
677
    case OT_LONG:
678
        tcg_gen_ext32u_tl(reg, reg);
679
        break;
680
    default:
681
        break;
682
    }
683
}
684

    
685
static void gen_exts(int ot, TCGv reg)
686
{
687
    switch(ot) {
688
    case OT_BYTE:
689
        tcg_gen_ext8s_tl(reg, reg);
690
        break;
691
    case OT_WORD:
692
        tcg_gen_ext16s_tl(reg, reg);
693
        break;
694
    case OT_LONG:
695
        tcg_gen_ext32s_tl(reg, reg);
696
        break;
697
    default:
698
        break;
699
    }
700
}
701

    
702
static inline void gen_op_jnz_ecx(int size, int label1)
703
{
704
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ECX]));
705
    gen_extu(size + 1, cpu_tmp0);
706
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
707
}
708

    
709
static inline void gen_op_jz_ecx(int size, int label1)
710
{
711
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ECX]));
712
    gen_extu(size + 1, cpu_tmp0);
713
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
714
}
715

    
716
static void gen_helper_in_func(int ot, TCGv v, TCGv_i32 n)
717
{
718
    switch (ot) {
719
    case 0: gen_helper_inb(v, n); break;
720
    case 1: gen_helper_inw(v, n); break;
721
    case 2: gen_helper_inl(v, n); break;
722
    }
723

    
724
}
725

    
726
static void gen_helper_out_func(int ot, TCGv_i32 v, TCGv_i32 n)
727
{
728
    switch (ot) {
729
    case 0: gen_helper_outb(v, n); break;
730
    case 1: gen_helper_outw(v, n); break;
731
    case 2: gen_helper_outl(v, n); break;
732
    }
733

    
734
}
735

    
736
static void gen_check_io(DisasContext *s, int ot, target_ulong cur_eip,
737
                         uint32_t svm_flags)
738
{
739
    int state_saved;
740
    target_ulong next_eip;
741

    
742
    state_saved = 0;
743
    if (s->pe && (s->cpl > s->iopl || s->vm86)) {
744
        if (s->cc_op != CC_OP_DYNAMIC)
745
            gen_op_set_cc_op(s->cc_op);
746
        gen_jmp_im(cur_eip);
747
        state_saved = 1;
748
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
749
        switch (ot) {
750
        case 0: gen_helper_check_iob(cpu_tmp2_i32); break;
751
        case 1: gen_helper_check_iow(cpu_tmp2_i32); break;
752
        case 2: gen_helper_check_iol(cpu_tmp2_i32); break;
753
        }
754
    }
755
    if(s->flags & HF_SVMI_MASK) {
756
        if (!state_saved) {
757
            if (s->cc_op != CC_OP_DYNAMIC)
758
                gen_op_set_cc_op(s->cc_op);
759
            gen_jmp_im(cur_eip);
760
            state_saved = 1;
761
        }
762
        svm_flags |= (1 << (4 + ot));
763
        next_eip = s->pc - s->cs_base;
764
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
765
        gen_helper_svm_check_io(cpu_tmp2_i32, tcg_const_i32(svm_flags),
766
                                tcg_const_i32(next_eip - cur_eip));
767
    }
768
}
769

    
770
static inline void gen_movs(DisasContext *s, int ot)
771
{
772
    gen_string_movl_A0_ESI(s);
773
    gen_op_ld_T0_A0(ot + s->mem_index);
774
    gen_string_movl_A0_EDI(s);
775
    gen_op_st_T0_A0(ot + s->mem_index);
776
    gen_op_movl_T0_Dshift(ot);
777
    gen_op_add_reg_T0(s->aflag, R_ESI);
778
    gen_op_add_reg_T0(s->aflag, R_EDI);
779
}
780

    
781
static inline void gen_update_cc_op(DisasContext *s)
782
{
783
    if (s->cc_op != CC_OP_DYNAMIC) {
784
        gen_op_set_cc_op(s->cc_op);
785
        s->cc_op = CC_OP_DYNAMIC;
786
    }
787
}
788

    
789
static void gen_op_update1_cc(void)
790
{
791
    tcg_gen_discard_tl(cpu_cc_src);
792
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
793
}
794

    
795
static void gen_op_update2_cc(void)
796
{
797
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
798
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
799
}
800

    
801
static inline void gen_op_cmpl_T0_T1_cc(void)
802
{
803
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
804
    tcg_gen_sub_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
805
}
806

    
807
static inline void gen_op_testl_T0_T1_cc(void)
808
{
809
    tcg_gen_discard_tl(cpu_cc_src);
810
    tcg_gen_and_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
811
}
812

    
813
static void gen_op_update_neg_cc(void)
814
{
815
    tcg_gen_neg_tl(cpu_cc_src, cpu_T[0]);
816
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
817
}
818

    
819
/* compute eflags.C to reg */
820
static void gen_compute_eflags_c(TCGv reg)
821
{
822
    gen_helper_cc_compute_c(cpu_tmp2_i32, cpu_cc_op);
823
    tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);
824
}
825

    
826
/* compute all eflags to cc_src */
827
static void gen_compute_eflags(TCGv reg)
828
{
829
    gen_helper_cc_compute_all(cpu_tmp2_i32, cpu_cc_op);
830
    tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);
831
}
832

    
833
static inline void gen_setcc_slow_T0(DisasContext *s, int jcc_op)
834
{
835
    if (s->cc_op != CC_OP_DYNAMIC)
836
        gen_op_set_cc_op(s->cc_op);
837
    switch(jcc_op) {
838
    case JCC_O:
839
        gen_compute_eflags(cpu_T[0]);
840
        tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 11);
841
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
842
        break;
843
    case JCC_B:
844
        gen_compute_eflags_c(cpu_T[0]);
845
        break;
846
    case JCC_Z:
847
        gen_compute_eflags(cpu_T[0]);
848
        tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 6);
849
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
850
        break;
851
    case JCC_BE:
852
        gen_compute_eflags(cpu_tmp0);
853
        tcg_gen_shri_tl(cpu_T[0], cpu_tmp0, 6);
854
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
855
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
856
        break;
857
    case JCC_S:
858
        gen_compute_eflags(cpu_T[0]);
859
        tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 7);
860
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
861
        break;
862
    case JCC_P:
863
        gen_compute_eflags(cpu_T[0]);
864
        tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 2);
865
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
866
        break;
867
    case JCC_L:
868
        gen_compute_eflags(cpu_tmp0);
869
        tcg_gen_shri_tl(cpu_T[0], cpu_tmp0, 11); /* CC_O */
870
        tcg_gen_shri_tl(cpu_tmp0, cpu_tmp0, 7); /* CC_S */
871
        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
872
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
873
        break;
874
    default:
875
    case JCC_LE:
876
        gen_compute_eflags(cpu_tmp0);
877
        tcg_gen_shri_tl(cpu_T[0], cpu_tmp0, 11); /* CC_O */
878
        tcg_gen_shri_tl(cpu_tmp4, cpu_tmp0, 7); /* CC_S */
879
        tcg_gen_shri_tl(cpu_tmp0, cpu_tmp0, 6); /* CC_Z */
880
        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
881
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
882
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
883
        break;
884
    }
885
}
886

    
887
/* return true if setcc_slow is not needed (WARNING: must be kept in
888
   sync with gen_jcc1) */
889
static int is_fast_jcc_case(DisasContext *s, int b)
890
{
891
    int jcc_op;
892
    jcc_op = (b >> 1) & 7;
893
    switch(s->cc_op) {
894
        /* we optimize the cmp/jcc case */
895
    case CC_OP_SUBB:
896
    case CC_OP_SUBW:
897
    case CC_OP_SUBL:
898
    case CC_OP_SUBQ:
899
        if (jcc_op == JCC_O || jcc_op == JCC_P)
900
            goto slow_jcc;
901
        break;
902

    
903
        /* some jumps are easy to compute */
904
    case CC_OP_ADDB:
905
    case CC_OP_ADDW:
906
    case CC_OP_ADDL:
907
    case CC_OP_ADDQ:
908

    
909
    case CC_OP_LOGICB:
910
    case CC_OP_LOGICW:
911
    case CC_OP_LOGICL:
912
    case CC_OP_LOGICQ:
913

    
914
    case CC_OP_INCB:
915
    case CC_OP_INCW:
916
    case CC_OP_INCL:
917
    case CC_OP_INCQ:
918

    
919
    case CC_OP_DECB:
920
    case CC_OP_DECW:
921
    case CC_OP_DECL:
922
    case CC_OP_DECQ:
923

    
924
    case CC_OP_SHLB:
925
    case CC_OP_SHLW:
926
    case CC_OP_SHLL:
927
    case CC_OP_SHLQ:
928
        if (jcc_op != JCC_Z && jcc_op != JCC_S)
929
            goto slow_jcc;
930
        break;
931
    default:
932
    slow_jcc:
933
        return 0;
934
    }
935
    return 1;
936
}
937

    
938
/* generate a conditional jump to label 'l1' according to jump opcode
939
   value 'b'. In the fast case, T0 is guaranted not to be used. */
940
static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1)
941
{
942
    int inv, jcc_op, size, cond;
943
    TCGv t0;
944

    
945
    inv = b & 1;
946
    jcc_op = (b >> 1) & 7;
947

    
948
    switch(cc_op) {
949
        /* we optimize the cmp/jcc case */
950
    case CC_OP_SUBB:
951
    case CC_OP_SUBW:
952
    case CC_OP_SUBL:
953
    case CC_OP_SUBQ:
954
        
955
        size = cc_op - CC_OP_SUBB;
956
        switch(jcc_op) {
957
        case JCC_Z:
958
        fast_jcc_z:
959
            switch(size) {
960
            case 0:
961
                tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xff);
962
                t0 = cpu_tmp0;
963
                break;
964
            case 1:
965
                tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xffff);
966
                t0 = cpu_tmp0;
967
                break;
968
#ifdef TARGET_X86_64
969
            case 2:
970
                tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xffffffff);
971
                t0 = cpu_tmp0;
972
                break;
973
#endif
974
            default:
975
                t0 = cpu_cc_dst;
976
                break;
977
            }
978
            tcg_gen_brcondi_tl(inv ? TCG_COND_NE : TCG_COND_EQ, t0, 0, l1);
979
            break;
980
        case JCC_S:
981
        fast_jcc_s:
982
            switch(size) {
983
            case 0:
984
                tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x80);
985
                tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, 
986
                                   0, l1);
987
                break;
988
            case 1:
989
                tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x8000);
990
                tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, 
991
                                   0, l1);
992
                break;
993
#ifdef TARGET_X86_64
994
            case 2:
995
                tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x80000000);
996
                tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, 
997
                                   0, l1);
998
                break;
999
#endif
1000
            default:
1001
                tcg_gen_brcondi_tl(inv ? TCG_COND_GE : TCG_COND_LT, cpu_cc_dst, 
1002
                                   0, l1);
1003
                break;
1004
            }
1005
            break;
1006
            
1007
        case JCC_B:
1008
            cond = inv ? TCG_COND_GEU : TCG_COND_LTU;
1009
            goto fast_jcc_b;
1010
        case JCC_BE:
1011
            cond = inv ? TCG_COND_GTU : TCG_COND_LEU;
1012
        fast_jcc_b:
1013
            tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);
1014
            switch(size) {
1015
            case 0:
1016
                t0 = cpu_tmp0;
1017
                tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xff);
1018
                tcg_gen_andi_tl(t0, cpu_cc_src, 0xff);
1019
                break;
1020
            case 1:
1021
                t0 = cpu_tmp0;
1022
                tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xffff);
1023
                tcg_gen_andi_tl(t0, cpu_cc_src, 0xffff);
1024
                break;
1025
#ifdef TARGET_X86_64
1026
            case 2:
1027
                t0 = cpu_tmp0;
1028
                tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xffffffff);
1029
                tcg_gen_andi_tl(t0, cpu_cc_src, 0xffffffff);
1030
                break;
1031
#endif
1032
            default:
1033
                t0 = cpu_cc_src;
1034
                break;
1035
            }
1036
            tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1);
1037
            break;
1038
            
1039
        case JCC_L:
1040
            cond = inv ? TCG_COND_GE : TCG_COND_LT;
1041
            goto fast_jcc_l;
1042
        case JCC_LE:
1043
            cond = inv ? TCG_COND_GT : TCG_COND_LE;
1044
        fast_jcc_l:
1045
            tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);
1046
            switch(size) {
1047
            case 0:
1048
                t0 = cpu_tmp0;
1049
                tcg_gen_ext8s_tl(cpu_tmp4, cpu_tmp4);
1050
                tcg_gen_ext8s_tl(t0, cpu_cc_src);
1051
                break;
1052
            case 1:
1053
                t0 = cpu_tmp0;
1054
                tcg_gen_ext16s_tl(cpu_tmp4, cpu_tmp4);
1055
                tcg_gen_ext16s_tl(t0, cpu_cc_src);
1056
                break;
1057
#ifdef TARGET_X86_64
1058
            case 2:
1059
                t0 = cpu_tmp0;
1060
                tcg_gen_ext32s_tl(cpu_tmp4, cpu_tmp4);
1061
                tcg_gen_ext32s_tl(t0, cpu_cc_src);
1062
                break;
1063
#endif
1064
            default:
1065
                t0 = cpu_cc_src;
1066
                break;
1067
            }
1068
            tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1);
1069
            break;
1070
            
1071
        default:
1072
            goto slow_jcc;
1073
        }
1074
        break;
1075
        
1076
        /* some jumps are easy to compute */
1077
    case CC_OP_ADDB:
1078
    case CC_OP_ADDW:
1079
    case CC_OP_ADDL:
1080
    case CC_OP_ADDQ:
1081
        
1082
    case CC_OP_ADCB:
1083
    case CC_OP_ADCW:
1084
    case CC_OP_ADCL:
1085
    case CC_OP_ADCQ:
1086
        
1087
    case CC_OP_SBBB:
1088
    case CC_OP_SBBW:
1089
    case CC_OP_SBBL:
1090
    case CC_OP_SBBQ:
1091
        
1092
    case CC_OP_LOGICB:
1093
    case CC_OP_LOGICW:
1094
    case CC_OP_LOGICL:
1095
    case CC_OP_LOGICQ:
1096
        
1097
    case CC_OP_INCB:
1098
    case CC_OP_INCW:
1099
    case CC_OP_INCL:
1100
    case CC_OP_INCQ:
1101
        
1102
    case CC_OP_DECB:
1103
    case CC_OP_DECW:
1104
    case CC_OP_DECL:
1105
    case CC_OP_DECQ:
1106
        
1107
    case CC_OP_SHLB:
1108
    case CC_OP_SHLW:
1109
    case CC_OP_SHLL:
1110
    case CC_OP_SHLQ:
1111
        
1112
    case CC_OP_SARB:
1113
    case CC_OP_SARW:
1114
    case CC_OP_SARL:
1115
    case CC_OP_SARQ:
1116
        switch(jcc_op) {
1117
        case JCC_Z:
1118
            size = (cc_op - CC_OP_ADDB) & 3;
1119
            goto fast_jcc_z;
1120
        case JCC_S:
1121
            size = (cc_op - CC_OP_ADDB) & 3;
1122
            goto fast_jcc_s;
1123
        default:
1124
            goto slow_jcc;
1125
        }
1126
        break;
1127
    default:
1128
    slow_jcc:
1129
        gen_setcc_slow_T0(s, jcc_op);
1130
        tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, 
1131
                           cpu_T[0], 0, l1);
1132
        break;
1133
    }
1134
}
1135

    
1136
/* XXX: does not work with gdbstub "ice" single step - not a
1137
   serious problem */
1138
static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
1139
{
1140
    int l1, l2;
1141

    
1142
    l1 = gen_new_label();
1143
    l2 = gen_new_label();
1144
    gen_op_jnz_ecx(s->aflag, l1);
1145
    gen_set_label(l2);
1146
    gen_jmp_tb(s, next_eip, 1);
1147
    gen_set_label(l1);
1148
    return l2;
1149
}
1150

    
1151
static inline void gen_stos(DisasContext *s, int ot)
1152
{
1153
    gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
1154
    gen_string_movl_A0_EDI(s);
1155
    gen_op_st_T0_A0(ot + s->mem_index);
1156
    gen_op_movl_T0_Dshift(ot);
1157
    gen_op_add_reg_T0(s->aflag, R_EDI);
1158
}
1159

    
1160
static inline void gen_lods(DisasContext *s, int ot)
1161
{
1162
    gen_string_movl_A0_ESI(s);
1163
    gen_op_ld_T0_A0(ot + s->mem_index);
1164
    gen_op_mov_reg_T0(ot, R_EAX);
1165
    gen_op_movl_T0_Dshift(ot);
1166
    gen_op_add_reg_T0(s->aflag, R_ESI);
1167
}
1168

    
1169
static inline void gen_scas(DisasContext *s, int ot)
1170
{
1171
    gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
1172
    gen_string_movl_A0_EDI(s);
1173
    gen_op_ld_T1_A0(ot + s->mem_index);
1174
    gen_op_cmpl_T0_T1_cc();
1175
    gen_op_movl_T0_Dshift(ot);
1176
    gen_op_add_reg_T0(s->aflag, R_EDI);
1177
}
1178

    
1179
static inline void gen_cmps(DisasContext *s, int ot)
1180
{
1181
    gen_string_movl_A0_ESI(s);
1182
    gen_op_ld_T0_A0(ot + s->mem_index);
1183
    gen_string_movl_A0_EDI(s);
1184
    gen_op_ld_T1_A0(ot + s->mem_index);
1185
    gen_op_cmpl_T0_T1_cc();
1186
    gen_op_movl_T0_Dshift(ot);
1187
    gen_op_add_reg_T0(s->aflag, R_ESI);
1188
    gen_op_add_reg_T0(s->aflag, R_EDI);
1189
}
1190

    
1191
static inline void gen_ins(DisasContext *s, int ot)
1192
{
1193
    if (use_icount)
1194
        gen_io_start();
1195
    gen_string_movl_A0_EDI(s);
1196
    /* Note: we must do this dummy write first to be restartable in
1197
       case of page fault. */
1198
    gen_op_movl_T0_0();
1199
    gen_op_st_T0_A0(ot + s->mem_index);
1200
    gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
1201
    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
1202
    tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1203
    gen_helper_in_func(ot, cpu_T[0], cpu_tmp2_i32);
1204
    gen_op_st_T0_A0(ot + s->mem_index);
1205
    gen_op_movl_T0_Dshift(ot);
1206
    gen_op_add_reg_T0(s->aflag, R_EDI);
1207
    if (use_icount)
1208
        gen_io_end();
1209
}
1210

    
1211
static inline void gen_outs(DisasContext *s, int ot)
1212
{
1213
    if (use_icount)
1214
        gen_io_start();
1215
    gen_string_movl_A0_ESI(s);
1216
    gen_op_ld_T0_A0(ot + s->mem_index);
1217

    
1218
    gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
1219
    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
1220
    tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1221
    tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]);
1222
    gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
1223

    
1224
    gen_op_movl_T0_Dshift(ot);
1225
    gen_op_add_reg_T0(s->aflag, R_ESI);
1226
    if (use_icount)
1227
        gen_io_end();
1228
}
1229

    
1230
/* same method as Valgrind : we generate jumps to current or next
1231
   instruction */
1232
#define GEN_REPZ(op)                                                          \
1233
static inline void gen_repz_ ## op(DisasContext *s, int ot,                   \
1234
                                 target_ulong cur_eip, target_ulong next_eip) \
1235
{                                                                             \
1236
    int l2;\
1237
    gen_update_cc_op(s);                                                      \
1238
    l2 = gen_jz_ecx_string(s, next_eip);                                      \
1239
    gen_ ## op(s, ot);                                                        \
1240
    gen_op_add_reg_im(s->aflag, R_ECX, -1);                                   \
1241
    /* a loop would cause two single step exceptions if ECX = 1               \
1242
       before rep string_insn */                                              \
1243
    if (!s->jmp_opt)                                                          \
1244
        gen_op_jz_ecx(s->aflag, l2);                                          \
1245
    gen_jmp(s, cur_eip);                                                      \
1246
}
1247

    
1248
#define GEN_REPZ2(op)                                                         \
1249
static inline void gen_repz_ ## op(DisasContext *s, int ot,                   \
1250
                                   target_ulong cur_eip,                      \
1251
                                   target_ulong next_eip,                     \
1252
                                   int nz)                                    \
1253
{                                                                             \
1254
    int l2;\
1255
    gen_update_cc_op(s);                                                      \
1256
    l2 = gen_jz_ecx_string(s, next_eip);                                      \
1257
    gen_ ## op(s, ot);                                                        \
1258
    gen_op_add_reg_im(s->aflag, R_ECX, -1);                                   \
1259
    gen_op_set_cc_op(CC_OP_SUBB + ot);                                        \
1260
    gen_jcc1(s, CC_OP_SUBB + ot, (JCC_Z << 1) | (nz ^ 1), l2);                \
1261
    if (!s->jmp_opt)                                                          \
1262
        gen_op_jz_ecx(s->aflag, l2);                                          \
1263
    gen_jmp(s, cur_eip);                                                      \
1264
}
1265

    
1266
GEN_REPZ(movs)
1267
GEN_REPZ(stos)
1268
GEN_REPZ(lods)
1269
GEN_REPZ(ins)
1270
GEN_REPZ(outs)
1271
GEN_REPZ2(scas)
1272
GEN_REPZ2(cmps)
1273

    
1274
static void gen_helper_fp_arith_ST0_FT0(int op)
1275
{
1276
    switch (op) {
1277
    case 0: gen_helper_fadd_ST0_FT0(); break;
1278
    case 1: gen_helper_fmul_ST0_FT0(); break;
1279
    case 2: gen_helper_fcom_ST0_FT0(); break;
1280
    case 3: gen_helper_fcom_ST0_FT0(); break;
1281
    case 4: gen_helper_fsub_ST0_FT0(); break;
1282
    case 5: gen_helper_fsubr_ST0_FT0(); break;
1283
    case 6: gen_helper_fdiv_ST0_FT0(); break;
1284
    case 7: gen_helper_fdivr_ST0_FT0(); break;
1285
    }
1286
}
1287

    
1288
/* NOTE the exception in "r" op ordering */
1289
static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1290
{
1291
    TCGv_i32 tmp = tcg_const_i32(opreg);
1292
    switch (op) {
1293
    case 0: gen_helper_fadd_STN_ST0(tmp); break;
1294
    case 1: gen_helper_fmul_STN_ST0(tmp); break;
1295
    case 4: gen_helper_fsubr_STN_ST0(tmp); break;
1296
    case 5: gen_helper_fsub_STN_ST0(tmp); break;
1297
    case 6: gen_helper_fdivr_STN_ST0(tmp); break;
1298
    case 7: gen_helper_fdiv_STN_ST0(tmp); break;
1299
    }
1300
}
1301

    
1302
/* if d == OR_TMP0, it means memory operand (address in A0) */
1303
static void gen_op(DisasContext *s1, int op, int ot, int d)
1304
{
1305
    if (d != OR_TMP0) {
1306
        gen_op_mov_TN_reg(ot, 0, d);
1307
    } else {
1308
        gen_op_ld_T0_A0(ot + s1->mem_index);
1309
    }
1310
    switch(op) {
1311
    case OP_ADCL:
1312
        if (s1->cc_op != CC_OP_DYNAMIC)
1313
            gen_op_set_cc_op(s1->cc_op);
1314
        gen_compute_eflags_c(cpu_tmp4);
1315
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1316
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
1317
        if (d != OR_TMP0)
1318
            gen_op_mov_reg_T0(ot, d);
1319
        else
1320
            gen_op_st_T0_A0(ot + s1->mem_index);
1321
        tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
1322
        tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1323
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp4);
1324
        tcg_gen_shli_i32(cpu_tmp2_i32, cpu_tmp2_i32, 2);
1325
        tcg_gen_addi_i32(cpu_cc_op, cpu_tmp2_i32, CC_OP_ADDB + ot);
1326
        s1->cc_op = CC_OP_DYNAMIC;
1327
        break;
1328
    case OP_SBBL:
1329
        if (s1->cc_op != CC_OP_DYNAMIC)
1330
            gen_op_set_cc_op(s1->cc_op);
1331
        gen_compute_eflags_c(cpu_tmp4);
1332
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1333
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
1334
        if (d != OR_TMP0)
1335
            gen_op_mov_reg_T0(ot, d);
1336
        else
1337
            gen_op_st_T0_A0(ot + s1->mem_index);
1338
        tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
1339
        tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1340
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp4);
1341
        tcg_gen_shli_i32(cpu_tmp2_i32, cpu_tmp2_i32, 2);
1342
        tcg_gen_addi_i32(cpu_cc_op, cpu_tmp2_i32, CC_OP_SUBB + ot);
1343
        s1->cc_op = CC_OP_DYNAMIC;
1344
        break;
1345
    case OP_ADDL:
1346
        gen_op_addl_T0_T1();
1347
        if (d != OR_TMP0)
1348
            gen_op_mov_reg_T0(ot, d);
1349
        else
1350
            gen_op_st_T0_A0(ot + s1->mem_index);
1351
        gen_op_update2_cc();
1352
        s1->cc_op = CC_OP_ADDB + ot;
1353
        break;
1354
    case OP_SUBL:
1355
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1356
        if (d != OR_TMP0)
1357
            gen_op_mov_reg_T0(ot, d);
1358
        else
1359
            gen_op_st_T0_A0(ot + s1->mem_index);
1360
        gen_op_update2_cc();
1361
        s1->cc_op = CC_OP_SUBB + ot;
1362
        break;
1363
    default:
1364
    case OP_ANDL:
1365
        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1366
        if (d != OR_TMP0)
1367
            gen_op_mov_reg_T0(ot, d);
1368
        else
1369
            gen_op_st_T0_A0(ot + s1->mem_index);
1370
        gen_op_update1_cc();
1371
        s1->cc_op = CC_OP_LOGICB + ot;
1372
        break;
1373
    case OP_ORL:
1374
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1375
        if (d != OR_TMP0)
1376
            gen_op_mov_reg_T0(ot, d);
1377
        else
1378
            gen_op_st_T0_A0(ot + s1->mem_index);
1379
        gen_op_update1_cc();
1380
        s1->cc_op = CC_OP_LOGICB + ot;
1381
        break;
1382
    case OP_XORL:
1383
        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1384
        if (d != OR_TMP0)
1385
            gen_op_mov_reg_T0(ot, d);
1386
        else
1387
            gen_op_st_T0_A0(ot + s1->mem_index);
1388
        gen_op_update1_cc();
1389
        s1->cc_op = CC_OP_LOGICB + ot;
1390
        break;
1391
    case OP_CMPL:
1392
        gen_op_cmpl_T0_T1_cc();
1393
        s1->cc_op = CC_OP_SUBB + ot;
1394
        break;
1395
    }
1396
}
1397

    
1398
/* if d == OR_TMP0, it means memory operand (address in A0) */
1399
static void gen_inc(DisasContext *s1, int ot, int d, int c)
1400
{
1401
    if (d != OR_TMP0)
1402
        gen_op_mov_TN_reg(ot, 0, d);
1403
    else
1404
        gen_op_ld_T0_A0(ot + s1->mem_index);
1405
    if (s1->cc_op != CC_OP_DYNAMIC)
1406
        gen_op_set_cc_op(s1->cc_op);
1407
    if (c > 0) {
1408
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 1);
1409
        s1->cc_op = CC_OP_INCB + ot;
1410
    } else {
1411
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], -1);
1412
        s1->cc_op = CC_OP_DECB + ot;
1413
    }
1414
    if (d != OR_TMP0)
1415
        gen_op_mov_reg_T0(ot, d);
1416
    else
1417
        gen_op_st_T0_A0(ot + s1->mem_index);
1418
    gen_compute_eflags_c(cpu_cc_src);
1419
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1420
}
1421

    
1422
static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, 
1423
                            int is_right, int is_arith)
1424
{
1425
    target_ulong mask;
1426
    int shift_label;
1427
    TCGv t0, t1;
1428

    
1429
    if (ot == OT_QUAD)
1430
        mask = 0x3f;
1431
    else
1432
        mask = 0x1f;
1433

    
1434
    /* load */
1435
    if (op1 == OR_TMP0)
1436
        gen_op_ld_T0_A0(ot + s->mem_index);
1437
    else
1438
        gen_op_mov_TN_reg(ot, 0, op1);
1439

    
1440
    tcg_gen_andi_tl(cpu_T[1], cpu_T[1], mask);
1441

    
1442
    tcg_gen_addi_tl(cpu_tmp5, cpu_T[1], -1);
1443

    
1444
    if (is_right) {
1445
        if (is_arith) {
1446
            gen_exts(ot, cpu_T[0]);
1447
            tcg_gen_sar_tl(cpu_T3, cpu_T[0], cpu_tmp5);
1448
            tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1449
        } else {
1450
            gen_extu(ot, cpu_T[0]);
1451
            tcg_gen_shr_tl(cpu_T3, cpu_T[0], cpu_tmp5);
1452
            tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1453
        }
1454
    } else {
1455
        tcg_gen_shl_tl(cpu_T3, cpu_T[0], cpu_tmp5);
1456
        tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1457
    }
1458

    
1459
    /* store */
1460
    if (op1 == OR_TMP0)
1461
        gen_op_st_T0_A0(ot + s->mem_index);
1462
    else
1463
        gen_op_mov_reg_T0(ot, op1);
1464
        
1465
    /* update eflags if non zero shift */
1466
    if (s->cc_op != CC_OP_DYNAMIC)
1467
        gen_op_set_cc_op(s->cc_op);
1468

    
1469
    /* XXX: inefficient */
1470
    t0 = tcg_temp_local_new();
1471
    t1 = tcg_temp_local_new();
1472

    
1473
    tcg_gen_mov_tl(t0, cpu_T[0]);
1474
    tcg_gen_mov_tl(t1, cpu_T3);
1475

    
1476
    shift_label = gen_new_label();
1477
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, shift_label);
1478

    
1479
    tcg_gen_mov_tl(cpu_cc_src, t1);
1480
    tcg_gen_mov_tl(cpu_cc_dst, t0);
1481
    if (is_right)
1482
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
1483
    else
1484
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
1485
        
1486
    gen_set_label(shift_label);
1487
    s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1488

    
1489
    tcg_temp_free(t0);
1490
    tcg_temp_free(t1);
1491
}
1492

    
1493
static void gen_shift_rm_im(DisasContext *s, int ot, int op1, int op2,
1494
                            int is_right, int is_arith)
1495
{
1496
    int mask;
1497
    
1498
    if (ot == OT_QUAD)
1499
        mask = 0x3f;
1500
    else
1501
        mask = 0x1f;
1502

    
1503
    /* load */
1504
    if (op1 == OR_TMP0)
1505
        gen_op_ld_T0_A0(ot + s->mem_index);
1506
    else
1507
        gen_op_mov_TN_reg(ot, 0, op1);
1508

    
1509
    op2 &= mask;
1510
    if (op2 != 0) {
1511
        if (is_right) {
1512
            if (is_arith) {
1513
                gen_exts(ot, cpu_T[0]);
1514
                tcg_gen_sari_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1515
                tcg_gen_sari_tl(cpu_T[0], cpu_T[0], op2);
1516
            } else {
1517
                gen_extu(ot, cpu_T[0]);
1518
                tcg_gen_shri_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1519
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], op2);
1520
            }
1521
        } else {
1522
            tcg_gen_shli_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1523
            tcg_gen_shli_tl(cpu_T[0], cpu_T[0], op2);
1524
        }
1525
    }
1526

    
1527
    /* store */
1528
    if (op1 == OR_TMP0)
1529
        gen_op_st_T0_A0(ot + s->mem_index);
1530
    else
1531
        gen_op_mov_reg_T0(ot, op1);
1532
        
1533
    /* update eflags if non zero shift */
1534
    if (op2 != 0) {
1535
        tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
1536
        tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1537
        if (is_right)
1538
            s->cc_op = CC_OP_SARB + ot;
1539
        else
1540
            s->cc_op = CC_OP_SHLB + ot;
1541
    }
1542
}
1543

    
1544
static inline void tcg_gen_lshift(TCGv ret, TCGv arg1, target_long arg2)
1545
{
1546
    if (arg2 >= 0)
1547
        tcg_gen_shli_tl(ret, arg1, arg2);
1548
    else
1549
        tcg_gen_shri_tl(ret, arg1, -arg2);
1550
}
1551

    
1552
static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, 
1553
                          int is_right)
1554
{
1555
    target_ulong mask;
1556
    int label1, label2, data_bits;
1557
    TCGv t0, t1, t2, a0;
1558

    
1559
    /* XXX: inefficient, but we must use local temps */
1560
    t0 = tcg_temp_local_new();
1561
    t1 = tcg_temp_local_new();
1562
    t2 = tcg_temp_local_new();
1563
    a0 = tcg_temp_local_new();
1564

    
1565
    if (ot == OT_QUAD)
1566
        mask = 0x3f;
1567
    else
1568
        mask = 0x1f;
1569

    
1570
    /* load */
1571
    if (op1 == OR_TMP0) {
1572
        tcg_gen_mov_tl(a0, cpu_A0);
1573
        gen_op_ld_v(ot + s->mem_index, t0, a0);
1574
    } else {
1575
        gen_op_mov_v_reg(ot, t0, op1);
1576
    }
1577

    
1578
    tcg_gen_mov_tl(t1, cpu_T[1]);
1579

    
1580
    tcg_gen_andi_tl(t1, t1, mask);
1581

    
1582
    /* Must test zero case to avoid using undefined behaviour in TCG
1583
       shifts. */
1584
    label1 = gen_new_label();
1585
    tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label1);
1586
    
1587
    if (ot <= OT_WORD)
1588
        tcg_gen_andi_tl(cpu_tmp0, t1, (1 << (3 + ot)) - 1);
1589
    else
1590
        tcg_gen_mov_tl(cpu_tmp0, t1);
1591
    
1592
    gen_extu(ot, t0);
1593
    tcg_gen_mov_tl(t2, t0);
1594

    
1595
    data_bits = 8 << ot;
1596
    /* XXX: rely on behaviour of shifts when operand 2 overflows (XXX:
1597
       fix TCG definition) */
1598
    if (is_right) {
1599
        tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp0);
1600
        tcg_gen_subfi_tl(cpu_tmp0, data_bits, cpu_tmp0);
1601
        tcg_gen_shl_tl(t0, t0, cpu_tmp0);
1602
    } else {
1603
        tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp0);
1604
        tcg_gen_subfi_tl(cpu_tmp0, data_bits, cpu_tmp0);
1605
        tcg_gen_shr_tl(t0, t0, cpu_tmp0);
1606
    }
1607
    tcg_gen_or_tl(t0, t0, cpu_tmp4);
1608

    
1609
    gen_set_label(label1);
1610
    /* store */
1611
    if (op1 == OR_TMP0) {
1612
        gen_op_st_v(ot + s->mem_index, t0, a0);
1613
    } else {
1614
        gen_op_mov_reg_v(ot, op1, t0);
1615
    }
1616
    
1617
    /* update eflags */
1618
    if (s->cc_op != CC_OP_DYNAMIC)
1619
        gen_op_set_cc_op(s->cc_op);
1620

    
1621
    label2 = gen_new_label();
1622
    tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label2);
1623

    
1624
    gen_compute_eflags(cpu_cc_src);
1625
    tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
1626
    tcg_gen_xor_tl(cpu_tmp0, t2, t0);
1627
    tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
1628
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
1629
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
1630
    if (is_right) {
1631
        tcg_gen_shri_tl(t0, t0, data_bits - 1);
1632
    }
1633
    tcg_gen_andi_tl(t0, t0, CC_C);
1634
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
1635
    
1636
    tcg_gen_discard_tl(cpu_cc_dst);
1637
    tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
1638
        
1639
    gen_set_label(label2);
1640
    s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1641

    
1642
    tcg_temp_free(t0);
1643
    tcg_temp_free(t1);
1644
    tcg_temp_free(t2);
1645
    tcg_temp_free(a0);
1646
}
1647

    
1648
static void gen_rot_rm_im(DisasContext *s, int ot, int op1, int op2,
1649
                          int is_right)
1650
{
1651
    int mask;
1652
    int data_bits;
1653
    TCGv t0, t1, a0;
1654

    
1655
    /* XXX: inefficient, but we must use local temps */
1656
    t0 = tcg_temp_local_new();
1657
    t1 = tcg_temp_local_new();
1658
    a0 = tcg_temp_local_new();
1659

    
1660
    if (ot == OT_QUAD)
1661
        mask = 0x3f;
1662
    else
1663
        mask = 0x1f;
1664

    
1665
    /* load */
1666
    if (op1 == OR_TMP0) {
1667
        tcg_gen_mov_tl(a0, cpu_A0);
1668
        gen_op_ld_v(ot + s->mem_index, t0, a0);
1669
    } else {
1670
        gen_op_mov_v_reg(ot, t0, op1);
1671
    }
1672

    
1673
    gen_extu(ot, t0);
1674
    tcg_gen_mov_tl(t1, t0);
1675

    
1676
    op2 &= mask;
1677
    data_bits = 8 << ot;
1678
    if (op2 != 0) {
1679
        int shift = op2 & ((1 << (3 + ot)) - 1);
1680
        if (is_right) {
1681
            tcg_gen_shri_tl(cpu_tmp4, t0, shift);
1682
            tcg_gen_shli_tl(t0, t0, data_bits - shift);
1683
        }
1684
        else {
1685
            tcg_gen_shli_tl(cpu_tmp4, t0, shift);
1686
            tcg_gen_shri_tl(t0, t0, data_bits - shift);
1687
        }
1688
        tcg_gen_or_tl(t0, t0, cpu_tmp4);
1689
    }
1690

    
1691
    /* store */
1692
    if (op1 == OR_TMP0) {
1693
        gen_op_st_v(ot + s->mem_index, t0, a0);
1694
    } else {
1695
        gen_op_mov_reg_v(ot, op1, t0);
1696
    }
1697

    
1698
    if (op2 != 0) {
1699
        /* update eflags */
1700
        if (s->cc_op != CC_OP_DYNAMIC)
1701
            gen_op_set_cc_op(s->cc_op);
1702

    
1703
        gen_compute_eflags(cpu_cc_src);
1704
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
1705
        tcg_gen_xor_tl(cpu_tmp0, t1, t0);
1706
        tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
1707
        tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
1708
        tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
1709
        if (is_right) {
1710
            tcg_gen_shri_tl(t0, t0, data_bits - 1);
1711
        }
1712
        tcg_gen_andi_tl(t0, t0, CC_C);
1713
        tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
1714

    
1715
        tcg_gen_discard_tl(cpu_cc_dst);
1716
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
1717
        s->cc_op = CC_OP_EFLAGS;
1718
    }
1719

    
1720
    tcg_temp_free(t0);
1721
    tcg_temp_free(t1);
1722
    tcg_temp_free(a0);
1723
}
1724

    
1725
/* XXX: add faster immediate = 1 case */
1726
static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, 
1727
                           int is_right)
1728
{
1729
    int label1;
1730

    
1731
    if (s->cc_op != CC_OP_DYNAMIC)
1732
        gen_op_set_cc_op(s->cc_op);
1733

    
1734
    /* load */
1735
    if (op1 == OR_TMP0)
1736
        gen_op_ld_T0_A0(ot + s->mem_index);
1737
    else
1738
        gen_op_mov_TN_reg(ot, 0, op1);
1739
    
1740
    if (is_right) {
1741
        switch (ot) {
1742
        case 0: gen_helper_rcrb(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1743
        case 1: gen_helper_rcrw(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1744
        case 2: gen_helper_rcrl(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1745
#ifdef TARGET_X86_64
1746
        case 3: gen_helper_rcrq(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1747
#endif
1748
        }
1749
    } else {
1750
        switch (ot) {
1751
        case 0: gen_helper_rclb(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1752
        case 1: gen_helper_rclw(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1753
        case 2: gen_helper_rcll(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1754
#ifdef TARGET_X86_64
1755
        case 3: gen_helper_rclq(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1756
#endif
1757
        }
1758
    }
1759
    /* store */
1760
    if (op1 == OR_TMP0)
1761
        gen_op_st_T0_A0(ot + s->mem_index);
1762
    else
1763
        gen_op_mov_reg_T0(ot, op1);
1764

    
1765
    /* update eflags */
1766
    label1 = gen_new_label();
1767
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cc_tmp, -1, label1);
1768

    
1769
    tcg_gen_mov_tl(cpu_cc_src, cpu_cc_tmp);
1770
    tcg_gen_discard_tl(cpu_cc_dst);
1771
    tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
1772
        
1773
    gen_set_label(label1);
1774
    s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1775
}
1776

    
1777
/* XXX: add faster immediate case */
1778
static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1, 
1779
                                int is_right)
1780
{
1781
    int label1, label2, data_bits;
1782
    target_ulong mask;
1783
    TCGv t0, t1, t2, a0;
1784

    
1785
    t0 = tcg_temp_local_new();
1786
    t1 = tcg_temp_local_new();
1787
    t2 = tcg_temp_local_new();
1788
    a0 = tcg_temp_local_new();
1789

    
1790
    if (ot == OT_QUAD)
1791
        mask = 0x3f;
1792
    else
1793
        mask = 0x1f;
1794

    
1795
    /* load */
1796
    if (op1 == OR_TMP0) {
1797
        tcg_gen_mov_tl(a0, cpu_A0);
1798
        gen_op_ld_v(ot + s->mem_index, t0, a0);
1799
    } else {
1800
        gen_op_mov_v_reg(ot, t0, op1);
1801
    }
1802

    
1803
    tcg_gen_andi_tl(cpu_T3, cpu_T3, mask);
1804

    
1805
    tcg_gen_mov_tl(t1, cpu_T[1]);
1806
    tcg_gen_mov_tl(t2, cpu_T3);
1807

    
1808
    /* Must test zero case to avoid using undefined behaviour in TCG
1809
       shifts. */
1810
    label1 = gen_new_label();
1811
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
1812
    
1813
    tcg_gen_addi_tl(cpu_tmp5, t2, -1);
1814
    if (ot == OT_WORD) {
1815
        /* Note: we implement the Intel behaviour for shift count > 16 */
1816
        if (is_right) {
1817
            tcg_gen_andi_tl(t0, t0, 0xffff);
1818
            tcg_gen_shli_tl(cpu_tmp0, t1, 16);
1819
            tcg_gen_or_tl(t0, t0, cpu_tmp0);
1820
            tcg_gen_ext32u_tl(t0, t0);
1821

    
1822
            tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
1823
            
1824
            /* only needed if count > 16, but a test would complicate */
1825
            tcg_gen_subfi_tl(cpu_tmp5, 32, t2);
1826
            tcg_gen_shl_tl(cpu_tmp0, t0, cpu_tmp5);
1827

    
1828
            tcg_gen_shr_tl(t0, t0, t2);
1829

    
1830
            tcg_gen_or_tl(t0, t0, cpu_tmp0);
1831
        } else {
1832
            /* XXX: not optimal */
1833
            tcg_gen_andi_tl(t0, t0, 0xffff);
1834
            tcg_gen_shli_tl(t1, t1, 16);
1835
            tcg_gen_or_tl(t1, t1, t0);
1836
            tcg_gen_ext32u_tl(t1, t1);
1837
            
1838
            tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
1839
            tcg_gen_subfi_tl(cpu_tmp0, 32, cpu_tmp5);
1840
            tcg_gen_shr_tl(cpu_tmp6, t1, cpu_tmp0);
1841
            tcg_gen_or_tl(cpu_tmp4, cpu_tmp4, cpu_tmp6);
1842

    
1843
            tcg_gen_shl_tl(t0, t0, t2);
1844
            tcg_gen_subfi_tl(cpu_tmp5, 32, t2);
1845
            tcg_gen_shr_tl(t1, t1, cpu_tmp5);
1846
            tcg_gen_or_tl(t0, t0, t1);
1847
        }
1848
    } else {
1849
        data_bits = 8 << ot;
1850
        if (is_right) {
1851
            if (ot == OT_LONG)
1852
                tcg_gen_ext32u_tl(t0, t0);
1853

    
1854
            tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
1855

    
1856
            tcg_gen_shr_tl(t0, t0, t2);
1857
            tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2);
1858
            tcg_gen_shl_tl(t1, t1, cpu_tmp5);
1859
            tcg_gen_or_tl(t0, t0, t1);
1860
            
1861
        } else {
1862
            if (ot == OT_LONG)
1863
                tcg_gen_ext32u_tl(t1, t1);
1864

    
1865
            tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
1866
            
1867
            tcg_gen_shl_tl(t0, t0, t2);
1868
            tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2);
1869
            tcg_gen_shr_tl(t1, t1, cpu_tmp5);
1870
            tcg_gen_or_tl(t0, t0, t1);
1871
        }
1872
    }
1873
    tcg_gen_mov_tl(t1, cpu_tmp4);
1874

    
1875
    gen_set_label(label1);
1876
    /* store */
1877
    if (op1 == OR_TMP0) {
1878
        gen_op_st_v(ot + s->mem_index, t0, a0);
1879
    } else {
1880
        gen_op_mov_reg_v(ot, op1, t0);
1881
    }
1882
    
1883
    /* update eflags */
1884
    if (s->cc_op != CC_OP_DYNAMIC)
1885
        gen_op_set_cc_op(s->cc_op);
1886

    
1887
    label2 = gen_new_label();
1888
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label2);
1889

    
1890
    tcg_gen_mov_tl(cpu_cc_src, t1);
1891
    tcg_gen_mov_tl(cpu_cc_dst, t0);
1892
    if (is_right) {
1893
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
1894
    } else {
1895
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
1896
    }
1897
    gen_set_label(label2);
1898
    s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1899

    
1900
    tcg_temp_free(t0);
1901
    tcg_temp_free(t1);
1902
    tcg_temp_free(t2);
1903
    tcg_temp_free(a0);
1904
}
1905

    
1906
static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
1907
{
1908
    if (s != OR_TMP1)
1909
        gen_op_mov_TN_reg(ot, 1, s);
1910
    switch(op) {
1911
    case OP_ROL:
1912
        gen_rot_rm_T1(s1, ot, d, 0);
1913
        break;
1914
    case OP_ROR:
1915
        gen_rot_rm_T1(s1, ot, d, 1);
1916
        break;
1917
    case OP_SHL:
1918
    case OP_SHL1:
1919
        gen_shift_rm_T1(s1, ot, d, 0, 0);
1920
        break;
1921
    case OP_SHR:
1922
        gen_shift_rm_T1(s1, ot, d, 1, 0);
1923
        break;
1924
    case OP_SAR:
1925
        gen_shift_rm_T1(s1, ot, d, 1, 1);
1926
        break;
1927
    case OP_RCL:
1928
        gen_rotc_rm_T1(s1, ot, d, 0);
1929
        break;
1930
    case OP_RCR:
1931
        gen_rotc_rm_T1(s1, ot, d, 1);
1932
        break;
1933
    }
1934
}
1935

    
1936
static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
1937
{
1938
    switch(op) {
1939
    case OP_ROL:
1940
        gen_rot_rm_im(s1, ot, d, c, 0);
1941
        break;
1942
    case OP_ROR:
1943
        gen_rot_rm_im(s1, ot, d, c, 1);
1944
        break;
1945
    case OP_SHL:
1946
    case OP_SHL1:
1947
        gen_shift_rm_im(s1, ot, d, c, 0, 0);
1948
        break;
1949
    case OP_SHR:
1950
        gen_shift_rm_im(s1, ot, d, c, 1, 0);
1951
        break;
1952
    case OP_SAR:
1953
        gen_shift_rm_im(s1, ot, d, c, 1, 1);
1954
        break;
1955
    default:
1956
        /* currently not optimized */
1957
        gen_op_movl_T1_im(c);
1958
        gen_shift(s1, op, ot, d, OR_TMP1);
1959
        break;
1960
    }
1961
}
1962

    
1963
static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr)
1964
{
1965
    target_long disp;
1966
    int havesib;
1967
    int base;
1968
    int index;
1969
    int scale;
1970
    int opreg;
1971
    int mod, rm, code, override, must_add_seg;
1972

    
1973
    override = s->override;
1974
    must_add_seg = s->addseg;
1975
    if (override >= 0)
1976
        must_add_seg = 1;
1977
    mod = (modrm >> 6) & 3;
1978
    rm = modrm & 7;
1979

    
1980
    if (s->aflag) {
1981

    
1982
        havesib = 0;
1983
        base = rm;
1984
        index = 0;
1985
        scale = 0;
1986

    
1987
        if (base == 4) {
1988
            havesib = 1;
1989
            code = ldub_code(s->pc++);
1990
            scale = (code >> 6) & 3;
1991
            index = ((code >> 3) & 7) | REX_X(s);
1992
            base = (code & 7);
1993
        }
1994
        base |= REX_B(s);
1995

    
1996
        switch (mod) {
1997
        case 0:
1998
            if ((base & 7) == 5) {
1999
                base = -1;
2000
                disp = (int32_t)ldl_code(s->pc);
2001
                s->pc += 4;
2002
                if (CODE64(s) && !havesib) {
2003
                    disp += s->pc + s->rip_offset;
2004
                }
2005
            } else {
2006
                disp = 0;
2007
            }
2008
            break;
2009
        case 1:
2010
            disp = (int8_t)ldub_code(s->pc++);
2011
            break;
2012
        default:
2013
        case 2:
2014
            disp = ldl_code(s->pc);
2015
            s->pc += 4;
2016
            break;
2017
        }
2018

    
2019
        if (base >= 0) {
2020
            /* for correct popl handling with esp */
2021
            if (base == 4 && s->popl_esp_hack)
2022
                disp += s->popl_esp_hack;
2023
#ifdef TARGET_X86_64
2024
            if (s->aflag == 2) {
2025
                gen_op_movq_A0_reg(base);
2026
                if (disp != 0) {
2027
                    gen_op_addq_A0_im(disp);
2028
                }
2029
            } else
2030
#endif
2031
            {
2032
                gen_op_movl_A0_reg(base);
2033
                if (disp != 0)
2034
                    gen_op_addl_A0_im(disp);
2035
            }
2036
        } else {
2037
#ifdef TARGET_X86_64
2038
            if (s->aflag == 2) {
2039
                gen_op_movq_A0_im(disp);
2040
            } else
2041
#endif
2042
            {
2043
                gen_op_movl_A0_im(disp);
2044
            }
2045
        }
2046
        /* XXX: index == 4 is always invalid */
2047
        if (havesib && (index != 4 || scale != 0)) {
2048
#ifdef TARGET_X86_64
2049
            if (s->aflag == 2) {
2050
                gen_op_addq_A0_reg_sN(scale, index);
2051
            } else
2052
#endif
2053
            {
2054
                gen_op_addl_A0_reg_sN(scale, index);
2055
            }
2056
        }
2057
        if (must_add_seg) {
2058
            if (override < 0) {
2059
                if (base == R_EBP || base == R_ESP)
2060
                    override = R_SS;
2061
                else
2062
                    override = R_DS;
2063
            }
2064
#ifdef TARGET_X86_64
2065
            if (s->aflag == 2) {
2066
                gen_op_addq_A0_seg(override);
2067
            } else
2068
#endif
2069
            {
2070
                gen_op_addl_A0_seg(override);
2071
            }
2072
        }
2073
    } else {
2074
        switch (mod) {
2075
        case 0:
2076
            if (rm == 6) {
2077
                disp = lduw_code(s->pc);
2078
                s->pc += 2;
2079
                gen_op_movl_A0_im(disp);
2080
                rm = 0; /* avoid SS override */
2081
                goto no_rm;
2082
            } else {
2083
                disp = 0;
2084
            }
2085
            break;
2086
        case 1:
2087
            disp = (int8_t)ldub_code(s->pc++);
2088
            break;
2089
        default:
2090
        case 2:
2091
            disp = lduw_code(s->pc);
2092
            s->pc += 2;
2093
            break;
2094
        }
2095
        switch(rm) {
2096
        case 0:
2097
            gen_op_movl_A0_reg(R_EBX);
2098
            gen_op_addl_A0_reg_sN(0, R_ESI);
2099
            break;
2100
        case 1:
2101
            gen_op_movl_A0_reg(R_EBX);
2102
            gen_op_addl_A0_reg_sN(0, R_EDI);
2103
            break;
2104
        case 2:
2105
            gen_op_movl_A0_reg(R_EBP);
2106
            gen_op_addl_A0_reg_sN(0, R_ESI);
2107
            break;
2108
        case 3:
2109
            gen_op_movl_A0_reg(R_EBP);
2110
            gen_op_addl_A0_reg_sN(0, R_EDI);
2111
            break;
2112
        case 4:
2113
            gen_op_movl_A0_reg(R_ESI);
2114
            break;
2115
        case 5:
2116
            gen_op_movl_A0_reg(R_EDI);
2117
            break;
2118
        case 6:
2119
            gen_op_movl_A0_reg(R_EBP);
2120
            break;
2121
        default:
2122
        case 7:
2123
            gen_op_movl_A0_reg(R_EBX);
2124
            break;
2125
        }
2126
        if (disp != 0)
2127
            gen_op_addl_A0_im(disp);
2128
        gen_op_andl_A0_ffff();
2129
    no_rm:
2130
        if (must_add_seg) {
2131
            if (override < 0) {
2132
                if (rm == 2 || rm == 3 || rm == 6)
2133
                    override = R_SS;
2134
                else
2135
                    override = R_DS;
2136
            }
2137
            gen_op_addl_A0_seg(override);
2138
        }
2139
    }
2140

    
2141
    opreg = OR_A0;
2142
    disp = 0;
2143
    *reg_ptr = opreg;
2144
    *offset_ptr = disp;
2145
}
2146

    
2147
static void gen_nop_modrm(DisasContext *s, int modrm)
2148
{
2149
    int mod, rm, base, code;
2150

    
2151
    mod = (modrm >> 6) & 3;
2152
    if (mod == 3)
2153
        return;
2154
    rm = modrm & 7;
2155

    
2156
    if (s->aflag) {
2157

    
2158
        base = rm;
2159

    
2160
        if (base == 4) {
2161
            code = ldub_code(s->pc++);
2162
            base = (code & 7);
2163
        }
2164

    
2165
        switch (mod) {
2166
        case 0:
2167
            if (base == 5) {
2168
                s->pc += 4;
2169
            }
2170
            break;
2171
        case 1:
2172
            s->pc++;
2173
            break;
2174
        default:
2175
        case 2:
2176
            s->pc += 4;
2177
            break;
2178
        }
2179
    } else {
2180
        switch (mod) {
2181
        case 0:
2182
            if (rm == 6) {
2183
                s->pc += 2;
2184
            }
2185
            break;
2186
        case 1:
2187
            s->pc++;
2188
            break;
2189
        default:
2190
        case 2:
2191
            s->pc += 2;
2192
            break;
2193
        }
2194
    }
2195
}
2196

    
2197
/* used for LEA and MOV AX, mem */
2198
static void gen_add_A0_ds_seg(DisasContext *s)
2199
{
2200
    int override, must_add_seg;
2201
    must_add_seg = s->addseg;
2202
    override = R_DS;
2203
    if (s->override >= 0) {
2204
        override = s->override;
2205
        must_add_seg = 1;
2206
    } else {
2207
        override = R_DS;
2208
    }
2209
    if (must_add_seg) {
2210
#ifdef TARGET_X86_64
2211
        if (CODE64(s)) {
2212
            gen_op_addq_A0_seg(override);
2213
        } else
2214
#endif
2215
        {
2216
            gen_op_addl_A0_seg(override);
2217
        }
2218
    }
2219
}
2220

    
2221
/* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2222
   OR_TMP0 */
2223
static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
2224
{
2225
    int mod, rm, opreg, disp;
2226

    
2227
    mod = (modrm >> 6) & 3;
2228
    rm = (modrm & 7) | REX_B(s);
2229
    if (mod == 3) {
2230
        if (is_store) {
2231
            if (reg != OR_TMP0)
2232
                gen_op_mov_TN_reg(ot, 0, reg);
2233
            gen_op_mov_reg_T0(ot, rm);
2234
        } else {
2235
            gen_op_mov_TN_reg(ot, 0, rm);
2236
            if (reg != OR_TMP0)
2237
                gen_op_mov_reg_T0(ot, reg);
2238
        }
2239
    } else {
2240
        gen_lea_modrm(s, modrm, &opreg, &disp);
2241
        if (is_store) {
2242
            if (reg != OR_TMP0)
2243
                gen_op_mov_TN_reg(ot, 0, reg);
2244
            gen_op_st_T0_A0(ot + s->mem_index);
2245
        } else {
2246
            gen_op_ld_T0_A0(ot + s->mem_index);
2247
            if (reg != OR_TMP0)
2248
                gen_op_mov_reg_T0(ot, reg);
2249
        }
2250
    }
2251
}
2252

    
2253
static inline uint32_t insn_get(DisasContext *s, int ot)
2254
{
2255
    uint32_t ret;
2256

    
2257
    switch(ot) {
2258
    case OT_BYTE:
2259
        ret = ldub_code(s->pc);
2260
        s->pc++;
2261
        break;
2262
    case OT_WORD:
2263
        ret = lduw_code(s->pc);
2264
        s->pc += 2;
2265
        break;
2266
    default:
2267
    case OT_LONG:
2268
        ret = ldl_code(s->pc);
2269
        s->pc += 4;
2270
        break;
2271
    }
2272
    return ret;
2273
}
2274

    
2275
static inline int insn_const_size(unsigned int ot)
2276
{
2277
    if (ot <= OT_LONG)
2278
        return 1 << ot;
2279
    else
2280
        return 4;
2281
}
2282

    
2283
static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
2284
{
2285
    TranslationBlock *tb;
2286
    target_ulong pc;
2287

    
2288
    pc = s->cs_base + eip;
2289
    tb = s->tb;
2290
    /* NOTE: we handle the case where the TB spans two pages here */
2291
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
2292
        (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
2293
        /* jump to same page: we can use a direct jump */
2294
        tcg_gen_goto_tb(tb_num);
2295
        gen_jmp_im(eip);
2296
        tcg_gen_exit_tb((long)tb + tb_num);
2297
    } else {
2298
        /* jump to another page: currently not optimized */
2299
        gen_jmp_im(eip);
2300
        gen_eob(s);
2301
    }
2302
}
2303

    
2304
static inline void gen_jcc(DisasContext *s, int b,
2305
                           target_ulong val, target_ulong next_eip)
2306
{
2307
    int l1, l2, cc_op;
2308

    
2309
    cc_op = s->cc_op;
2310
    if (s->cc_op != CC_OP_DYNAMIC) {
2311
        gen_op_set_cc_op(s->cc_op);
2312
        s->cc_op = CC_OP_DYNAMIC;
2313
    }
2314
    if (s->jmp_opt) {
2315
        l1 = gen_new_label();
2316
        gen_jcc1(s, cc_op, b, l1);
2317
        
2318
        gen_goto_tb(s, 0, next_eip);
2319

    
2320
        gen_set_label(l1);
2321
        gen_goto_tb(s, 1, val);
2322
        s->is_jmp = 3;
2323
    } else {
2324

    
2325
        l1 = gen_new_label();
2326
        l2 = gen_new_label();
2327
        gen_jcc1(s, cc_op, b, l1);
2328

    
2329
        gen_jmp_im(next_eip);
2330
        tcg_gen_br(l2);
2331

    
2332
        gen_set_label(l1);
2333
        gen_jmp_im(val);
2334
        gen_set_label(l2);
2335
        gen_eob(s);
2336
    }
2337
}
2338

    
2339
static void gen_setcc(DisasContext *s, int b)
2340
{
2341
    int inv, jcc_op, l1;
2342
    TCGv t0;
2343

    
2344
    if (is_fast_jcc_case(s, b)) {
2345
        /* nominal case: we use a jump */
2346
        /* XXX: make it faster by adding new instructions in TCG */
2347
        t0 = tcg_temp_local_new();
2348
        tcg_gen_movi_tl(t0, 0);
2349
        l1 = gen_new_label();
2350
        gen_jcc1(s, s->cc_op, b ^ 1, l1);
2351
        tcg_gen_movi_tl(t0, 1);
2352
        gen_set_label(l1);
2353
        tcg_gen_mov_tl(cpu_T[0], t0);
2354
        tcg_temp_free(t0);
2355
    } else {
2356
        /* slow case: it is more efficient not to generate a jump,
2357
           although it is questionnable whether this optimization is
2358
           worth to */
2359
        inv = b & 1;
2360
        jcc_op = (b >> 1) & 7;
2361
        gen_setcc_slow_T0(s, jcc_op);
2362
        if (inv) {
2363
            tcg_gen_xori_tl(cpu_T[0], cpu_T[0], 1);
2364
        }
2365
    }
2366
}
2367

    
2368
static inline void gen_op_movl_T0_seg(int seg_reg)
2369
{
2370
    tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
2371
                     offsetof(CPUX86State,segs[seg_reg].selector));
2372
}
2373

    
2374
static inline void gen_op_movl_seg_T0_vm(int seg_reg)
2375
{
2376
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
2377
    tcg_gen_st32_tl(cpu_T[0], cpu_env, 
2378
                    offsetof(CPUX86State,segs[seg_reg].selector));
2379
    tcg_gen_shli_tl(cpu_T[0], cpu_T[0], 4);
2380
    tcg_gen_st_tl(cpu_T[0], cpu_env, 
2381
                  offsetof(CPUX86State,segs[seg_reg].base));
2382
}
2383

    
2384
/* move T0 to seg_reg and compute if the CPU state may change. Never
2385
   call this function with seg_reg == R_CS */
2386
static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
2387
{
2388
    if (s->pe && !s->vm86) {
2389
        /* XXX: optimize by finding processor state dynamically */
2390
        if (s->cc_op != CC_OP_DYNAMIC)
2391
            gen_op_set_cc_op(s->cc_op);
2392
        gen_jmp_im(cur_eip);
2393
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
2394
        gen_helper_load_seg(tcg_const_i32(seg_reg), cpu_tmp2_i32);
2395
        /* abort translation because the addseg value may change or
2396
           because ss32 may change. For R_SS, translation must always
2397
           stop as a special handling must be done to disable hardware
2398
           interrupts for the next instruction */
2399
        if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
2400
            s->is_jmp = 3;
2401
    } else {
2402
        gen_op_movl_seg_T0_vm(seg_reg);
2403
        if (seg_reg == R_SS)
2404
            s->is_jmp = 3;
2405
    }
2406
}
2407

    
2408
static inline int svm_is_rep(int prefixes)
2409
{
2410
    return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
2411
}
2412

    
2413
static inline void
2414
gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2415
                              uint32_t type, uint64_t param)
2416
{
2417
    /* no SVM activated; fast case */
2418
    if (likely(!(s->flags & HF_SVMI_MASK)))
2419
        return;
2420
    if (s->cc_op != CC_OP_DYNAMIC)
2421
        gen_op_set_cc_op(s->cc_op);
2422
    gen_jmp_im(pc_start - s->cs_base);
2423
    gen_helper_svm_check_intercept_param(tcg_const_i32(type),
2424
                                         tcg_const_i64(param));
2425
}
2426

    
2427
static inline void
2428
gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
2429
{
2430
    gen_svm_check_intercept_param(s, pc_start, type, 0);
2431
}
2432

    
2433
static inline void gen_stack_update(DisasContext *s, int addend)
2434
{
2435
#ifdef TARGET_X86_64
2436
    if (CODE64(s)) {
2437
        gen_op_add_reg_im(2, R_ESP, addend);
2438
    } else
2439
#endif
2440
    if (s->ss32) {
2441
        gen_op_add_reg_im(1, R_ESP, addend);
2442
    } else {
2443
        gen_op_add_reg_im(0, R_ESP, addend);
2444
    }
2445
}
2446

    
2447
/* generate a push. It depends on ss32, addseg and dflag */
2448
static void gen_push_T0(DisasContext *s)
2449
{
2450
#ifdef TARGET_X86_64
2451
    if (CODE64(s)) {
2452
        gen_op_movq_A0_reg(R_ESP);
2453
        if (s->dflag) {
2454
            gen_op_addq_A0_im(-8);
2455
            gen_op_st_T0_A0(OT_QUAD + s->mem_index);
2456
        } else {
2457
            gen_op_addq_A0_im(-2);
2458
            gen_op_st_T0_A0(OT_WORD + s->mem_index);
2459
        }
2460
        gen_op_mov_reg_A0(2, R_ESP);
2461
    } else
2462
#endif
2463
    {
2464
        gen_op_movl_A0_reg(R_ESP);
2465
        if (!s->dflag)
2466
            gen_op_addl_A0_im(-2);
2467
        else
2468
            gen_op_addl_A0_im(-4);
2469
        if (s->ss32) {
2470
            if (s->addseg) {
2471
                tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2472
                gen_op_addl_A0_seg(R_SS);
2473
            }
2474
        } else {
2475
            gen_op_andl_A0_ffff();
2476
            tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2477
            gen_op_addl_A0_seg(R_SS);
2478
        }
2479
        gen_op_st_T0_A0(s->dflag + 1 + s->mem_index);
2480
        if (s->ss32 && !s->addseg)
2481
            gen_op_mov_reg_A0(1, R_ESP);
2482
        else
2483
            gen_op_mov_reg_T1(s->ss32 + 1, R_ESP);
2484
    }
2485
}
2486

    
2487
/* generate a push. It depends on ss32, addseg and dflag */
2488
/* slower version for T1, only used for call Ev */
2489
static void gen_push_T1(DisasContext *s)
2490
{
2491
#ifdef TARGET_X86_64
2492
    if (CODE64(s)) {
2493
        gen_op_movq_A0_reg(R_ESP);
2494
        if (s->dflag) {
2495
            gen_op_addq_A0_im(-8);
2496
            gen_op_st_T1_A0(OT_QUAD + s->mem_index);
2497
        } else {
2498
            gen_op_addq_A0_im(-2);
2499
            gen_op_st_T0_A0(OT_WORD + s->mem_index);
2500
        }
2501
        gen_op_mov_reg_A0(2, R_ESP);
2502
    } else
2503
#endif
2504
    {
2505
        gen_op_movl_A0_reg(R_ESP);
2506
        if (!s->dflag)
2507
            gen_op_addl_A0_im(-2);
2508
        else
2509
            gen_op_addl_A0_im(-4);
2510
        if (s->ss32) {
2511
            if (s->addseg) {
2512
                gen_op_addl_A0_seg(R_SS);
2513
            }
2514
        } else {
2515
            gen_op_andl_A0_ffff();
2516
            gen_op_addl_A0_seg(R_SS);
2517
        }
2518
        gen_op_st_T1_A0(s->dflag + 1 + s->mem_index);
2519

    
2520
        if (s->ss32 && !s->addseg)
2521
            gen_op_mov_reg_A0(1, R_ESP);
2522
        else
2523
            gen_stack_update(s, (-2) << s->dflag);
2524
    }
2525
}
2526

    
2527
/* two step pop is necessary for precise exceptions */
2528
static void gen_pop_T0(DisasContext *s)
2529
{
2530
#ifdef TARGET_X86_64
2531
    if (CODE64(s)) {
2532
        gen_op_movq_A0_reg(R_ESP);
2533
        gen_op_ld_T0_A0((s->dflag ? OT_QUAD : OT_WORD) + s->mem_index);
2534
    } else
2535
#endif
2536
    {
2537
        gen_op_movl_A0_reg(R_ESP);
2538
        if (s->ss32) {
2539
            if (s->addseg)
2540
                gen_op_addl_A0_seg(R_SS);
2541
        } else {
2542
            gen_op_andl_A0_ffff();
2543
            gen_op_addl_A0_seg(R_SS);
2544
        }
2545
        gen_op_ld_T0_A0(s->dflag + 1 + s->mem_index);
2546
    }
2547
}
2548

    
2549
static void gen_pop_update(DisasContext *s)
2550
{
2551
#ifdef TARGET_X86_64
2552
    if (CODE64(s) && s->dflag) {
2553
        gen_stack_update(s, 8);
2554
    } else
2555
#endif
2556
    {
2557
        gen_stack_update(s, 2 << s->dflag);
2558
    }
2559
}
2560

    
2561
static void gen_stack_A0(DisasContext *s)
2562
{
2563
    gen_op_movl_A0_reg(R_ESP);
2564
    if (!s->ss32)
2565
        gen_op_andl_A0_ffff();
2566
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2567
    if (s->addseg)
2568
        gen_op_addl_A0_seg(R_SS);
2569
}
2570

    
2571
/* NOTE: wrap around in 16 bit not fully handled */
2572
static void gen_pusha(DisasContext *s)
2573
{
2574
    int i;
2575
    gen_op_movl_A0_reg(R_ESP);
2576
    gen_op_addl_A0_im(-16 <<  s->dflag);
2577
    if (!s->ss32)
2578
        gen_op_andl_A0_ffff();
2579
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2580
    if (s->addseg)
2581
        gen_op_addl_A0_seg(R_SS);
2582
    for(i = 0;i < 8; i++) {
2583
        gen_op_mov_TN_reg(OT_LONG, 0, 7 - i);
2584
        gen_op_st_T0_A0(OT_WORD + s->dflag + s->mem_index);
2585
        gen_op_addl_A0_im(2 <<  s->dflag);
2586
    }
2587
    gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2588
}
2589

    
2590
/* NOTE: wrap around in 16 bit not fully handled */
2591
static void gen_popa(DisasContext *s)
2592
{
2593
    int i;
2594
    gen_op_movl_A0_reg(R_ESP);
2595
    if (!s->ss32)
2596
        gen_op_andl_A0_ffff();
2597
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2598
    tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 16 <<  s->dflag);
2599
    if (s->addseg)
2600
        gen_op_addl_A0_seg(R_SS);
2601
    for(i = 0;i < 8; i++) {
2602
        /* ESP is not reloaded */
2603
        if (i != 3) {
2604
            gen_op_ld_T0_A0(OT_WORD + s->dflag + s->mem_index);
2605
            gen_op_mov_reg_T0(OT_WORD + s->dflag, 7 - i);
2606
        }
2607
        gen_op_addl_A0_im(2 <<  s->dflag);
2608
    }
2609
    gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2610
}
2611

    
2612
static void gen_enter(DisasContext *s, int esp_addend, int level)
2613
{
2614
    int ot, opsize;
2615

    
2616
    level &= 0x1f;
2617
#ifdef TARGET_X86_64
2618
    if (CODE64(s)) {
2619
        ot = s->dflag ? OT_QUAD : OT_WORD;
2620
        opsize = 1 << ot;
2621

    
2622
        gen_op_movl_A0_reg(R_ESP);
2623
        gen_op_addq_A0_im(-opsize);
2624
        tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2625

    
2626
        /* push bp */
2627
        gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
2628
        gen_op_st_T0_A0(ot + s->mem_index);
2629
        if (level) {
2630
            /* XXX: must save state */
2631
            gen_helper_enter64_level(tcg_const_i32(level),
2632
                                     tcg_const_i32((ot == OT_QUAD)),
2633
                                     cpu_T[1]);
2634
        }
2635
        gen_op_mov_reg_T1(ot, R_EBP);
2636
        tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2637
        gen_op_mov_reg_T1(OT_QUAD, R_ESP);
2638
    } else
2639
#endif
2640
    {
2641
        ot = s->dflag + OT_WORD;
2642
        opsize = 2 << s->dflag;
2643

    
2644
        gen_op_movl_A0_reg(R_ESP);
2645
        gen_op_addl_A0_im(-opsize);
2646
        if (!s->ss32)
2647
            gen_op_andl_A0_ffff();
2648
        tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2649
        if (s->addseg)
2650
            gen_op_addl_A0_seg(R_SS);
2651
        /* push bp */
2652
        gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
2653
        gen_op_st_T0_A0(ot + s->mem_index);
2654
        if (level) {
2655
            /* XXX: must save state */
2656
            gen_helper_enter_level(tcg_const_i32(level),
2657
                                   tcg_const_i32(s->dflag),
2658
                                   cpu_T[1]);
2659
        }
2660
        gen_op_mov_reg_T1(ot, R_EBP);
2661
        tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2662
        gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2663
    }
2664
}
2665

    
2666
static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2667
{
2668
    if (s->cc_op != CC_OP_DYNAMIC)
2669
        gen_op_set_cc_op(s->cc_op);
2670
    gen_jmp_im(cur_eip);
2671
    gen_helper_raise_exception(tcg_const_i32(trapno));
2672
    s->is_jmp = 3;
2673
}
2674

    
2675
/* an interrupt is different from an exception because of the
2676
   privilege checks */
2677
static void gen_interrupt(DisasContext *s, int intno,
2678
                          target_ulong cur_eip, target_ulong next_eip)
2679
{
2680
    if (s->cc_op != CC_OP_DYNAMIC)
2681
        gen_op_set_cc_op(s->cc_op);
2682
    gen_jmp_im(cur_eip);
2683
    gen_helper_raise_interrupt(tcg_const_i32(intno), 
2684
                               tcg_const_i32(next_eip - cur_eip));
2685
    s->is_jmp = 3;
2686
}
2687

    
2688
static void gen_debug(DisasContext *s, target_ulong cur_eip)
2689
{
2690
    if (s->cc_op != CC_OP_DYNAMIC)
2691
        gen_op_set_cc_op(s->cc_op);
2692
    gen_jmp_im(cur_eip);
2693
    gen_helper_debug();
2694
    s->is_jmp = 3;
2695
}
2696

    
2697
/* generate a generic end of block. Trace exception is also generated
2698
   if needed */
2699
static void gen_eob(DisasContext *s)
2700
{
2701
    if (s->cc_op != CC_OP_DYNAMIC)
2702
        gen_op_set_cc_op(s->cc_op);
2703
    if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
2704
        gen_helper_reset_inhibit_irq();
2705
    }
2706
    if (s->tb->flags & HF_RF_MASK) {
2707
        gen_helper_reset_rf();
2708
    }
2709
    if (s->singlestep_enabled) {
2710
        gen_helper_debug();
2711
    } else if (s->tf) {
2712
        gen_helper_single_step();
2713
    } else {
2714
        tcg_gen_exit_tb(0);
2715
    }
2716
    s->is_jmp = 3;
2717
}
2718

    
2719
/* generate a jump to eip. No segment change must happen before as a
2720
   direct call to the next block may occur */
2721
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2722
{
2723
    if (s->jmp_opt) {
2724
        if (s->cc_op != CC_OP_DYNAMIC) {
2725
            gen_op_set_cc_op(s->cc_op);
2726
            s->cc_op = CC_OP_DYNAMIC;
2727
        }
2728
        gen_goto_tb(s, tb_num, eip);
2729
        s->is_jmp = 3;
2730
    } else {
2731
        gen_jmp_im(eip);
2732
        gen_eob(s);
2733
    }
2734
}
2735

    
2736
static void gen_jmp(DisasContext *s, target_ulong eip)
2737
{
2738
    gen_jmp_tb(s, eip, 0);
2739
}
2740

    
2741
static inline void gen_ldq_env_A0(int idx, int offset)
2742
{
2743
    int mem_index = (idx >> 2) - 1;
2744
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2745
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
2746
}
2747

    
2748
static inline void gen_stq_env_A0(int idx, int offset)
2749
{
2750
    int mem_index = (idx >> 2) - 1;
2751
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
2752
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2753
}
2754

    
2755
static inline void gen_ldo_env_A0(int idx, int offset)
2756
{
2757
    int mem_index = (idx >> 2) - 1;
2758
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2759
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2760
    tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2761
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2762
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2763
}
2764

    
2765
static inline void gen_sto_env_A0(int idx, int offset)
2766
{
2767
    int mem_index = (idx >> 2) - 1;
2768
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2769
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2770
    tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2771
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2772
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2773
}
2774

    
2775
static inline void gen_op_movo(int d_offset, int s_offset)
2776
{
2777
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2778
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2779
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + 8);
2780
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + 8);
2781
}
2782

    
2783
static inline void gen_op_movq(int d_offset, int s_offset)
2784
{
2785
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2786
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2787
}
2788

    
2789
static inline void gen_op_movl(int d_offset, int s_offset)
2790
{
2791
    tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
2792
    tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
2793
}
2794

    
2795
static inline void gen_op_movq_env_0(int d_offset)
2796
{
2797
    tcg_gen_movi_i64(cpu_tmp1_i64, 0);
2798
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2799
}
2800

    
2801
#define SSE_SPECIAL ((void *)1)
2802
#define SSE_DUMMY ((void *)2)
2803

    
2804
#define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2805
#define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2806
                     gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2807

    
2808
static void *sse_op_table1[256][4] = {
2809
    /* 3DNow! extensions */
2810
    [0x0e] = { SSE_DUMMY }, /* femms */
2811
    [0x0f] = { SSE_DUMMY }, /* pf... */
2812
    /* pure SSE operations */
2813
    [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2814
    [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2815
    [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2816
    [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
2817
    [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
2818
    [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
2819
    [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */
2820
    [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */
2821

    
2822
    [0x28] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2823
    [0x29] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2824
    [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2825
    [0x2b] = { SSE_SPECIAL, SSE_SPECIAL },  /* movntps, movntpd */
2826
    [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2827
    [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2828
    [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd },
2829
    [0x2f] = { gen_helper_comiss, gen_helper_comisd },
2830
    [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2831
    [0x51] = SSE_FOP(sqrt),
2832
    [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL },
2833
    [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL },
2834
    [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */
2835
    [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */
2836
    [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */
2837
    [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */
2838
    [0x58] = SSE_FOP(add),
2839
    [0x59] = SSE_FOP(mul),
2840
    [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps,
2841
               gen_helper_cvtss2sd, gen_helper_cvtsd2ss },
2842
    [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq },
2843
    [0x5c] = SSE_FOP(sub),
2844
    [0x5d] = SSE_FOP(min),
2845
    [0x5e] = SSE_FOP(div),
2846
    [0x5f] = SSE_FOP(max),
2847

    
2848
    [0xc2] = SSE_FOP(cmpeq),
2849
    [0xc6] = { gen_helper_shufps, gen_helper_shufpd },
2850

    
2851
    [0x38] = { SSE_SPECIAL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* SSSE3/SSE4 */
2852
    [0x3a] = { SSE_SPECIAL, SSE_SPECIAL }, /* SSSE3/SSE4 */
2853

    
2854
    /* MMX ops and their SSE extensions */
2855
    [0x60] = MMX_OP2(punpcklbw),
2856
    [0x61] = MMX_OP2(punpcklwd),
2857
    [0x62] = MMX_OP2(punpckldq),
2858
    [0x63] = MMX_OP2(packsswb),
2859
    [0x64] = MMX_OP2(pcmpgtb),
2860
    [0x65] = MMX_OP2(pcmpgtw),
2861
    [0x66] = MMX_OP2(pcmpgtl),
2862
    [0x67] = MMX_OP2(packuswb),
2863
    [0x68] = MMX_OP2(punpckhbw),
2864
    [0x69] = MMX_OP2(punpckhwd),
2865
    [0x6a] = MMX_OP2(punpckhdq),
2866
    [0x6b] = MMX_OP2(packssdw),
2867
    [0x6c] = { NULL, gen_helper_punpcklqdq_xmm },
2868
    [0x6d] = { NULL, gen_helper_punpckhqdq_xmm },
2869
    [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
2870
    [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
2871
    [0x70] = { gen_helper_pshufw_mmx,
2872
               gen_helper_pshufd_xmm,
2873
               gen_helper_pshufhw_xmm,
2874
               gen_helper_pshuflw_xmm },
2875
    [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
2876
    [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
2877
    [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
2878
    [0x74] = MMX_OP2(pcmpeqb),
2879
    [0x75] = MMX_OP2(pcmpeqw),
2880
    [0x76] = MMX_OP2(pcmpeql),
2881
    [0x77] = { SSE_DUMMY }, /* emms */
2882
    [0x7c] = { NULL, gen_helper_haddpd, NULL, gen_helper_haddps },
2883
    [0x7d] = { NULL, gen_helper_hsubpd, NULL, gen_helper_hsubps },
2884
    [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
2885
    [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
2886
    [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
2887
    [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
2888
    [0xd0] = { NULL, gen_helper_addsubpd, NULL, gen_helper_addsubps },
2889
    [0xd1] = MMX_OP2(psrlw),
2890
    [0xd2] = MMX_OP2(psrld),
2891
    [0xd3] = MMX_OP2(psrlq),
2892
    [0xd4] = MMX_OP2(paddq),
2893
    [0xd5] = MMX_OP2(pmullw),
2894
    [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2895
    [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
2896
    [0xd8] = MMX_OP2(psubusb),
2897
    [0xd9] = MMX_OP2(psubusw),
2898
    [0xda] = MMX_OP2(pminub),
2899
    [0xdb] = MMX_OP2(pand),
2900
    [0xdc] = MMX_OP2(paddusb),
2901
    [0xdd] = MMX_OP2(paddusw),
2902
    [0xde] = MMX_OP2(pmaxub),
2903
    [0xdf] = MMX_OP2(pandn),
2904
    [0xe0] = MMX_OP2(pavgb),
2905
    [0xe1] = MMX_OP2(psraw),
2906
    [0xe2] = MMX_OP2(psrad),
2907
    [0xe3] = MMX_OP2(pavgw),
2908
    [0xe4] = MMX_OP2(pmulhuw),
2909
    [0xe5] = MMX_OP2(pmulhw),
2910
    [0xe6] = { NULL, gen_helper_cvttpd2dq, gen_helper_cvtdq2pd, gen_helper_cvtpd2dq },
2911
    [0xe7] = { SSE_SPECIAL , SSE_SPECIAL },  /* movntq, movntq */
2912
    [0xe8] = MMX_OP2(psubsb),
2913
    [0xe9] = MMX_OP2(psubsw),
2914
    [0xea] = MMX_OP2(pminsw),
2915
    [0xeb] = MMX_OP2(por),
2916
    [0xec] = MMX_OP2(paddsb),
2917
    [0xed] = MMX_OP2(paddsw),
2918
    [0xee] = MMX_OP2(pmaxsw),
2919
    [0xef] = MMX_OP2(pxor),
2920
    [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
2921
    [0xf1] = MMX_OP2(psllw),
2922
    [0xf2] = MMX_OP2(pslld),
2923
    [0xf3] = MMX_OP2(psllq),
2924
    [0xf4] = MMX_OP2(pmuludq),
2925
    [0xf5] = MMX_OP2(pmaddwd),
2926
    [0xf6] = MMX_OP2(psadbw),
2927
    [0xf7] = MMX_OP2(maskmov),
2928
    [0xf8] = MMX_OP2(psubb),
2929
    [0xf9] = MMX_OP2(psubw),
2930
    [0xfa] = MMX_OP2(psubl),
2931
    [0xfb] = MMX_OP2(psubq),
2932
    [0xfc] = MMX_OP2(paddb),
2933
    [0xfd] = MMX_OP2(paddw),
2934
    [0xfe] = MMX_OP2(paddl),
2935
};
2936

    
2937
static void *sse_op_table2[3 * 8][2] = {
2938
    [0 + 2] = MMX_OP2(psrlw),
2939
    [0 + 4] = MMX_OP2(psraw),
2940
    [0 + 6] = MMX_OP2(psllw),
2941
    [8 + 2] = MMX_OP2(psrld),
2942
    [8 + 4] = MMX_OP2(psrad),
2943
    [8 + 6] = MMX_OP2(pslld),
2944
    [16 + 2] = MMX_OP2(psrlq),
2945
    [16 + 3] = { NULL, gen_helper_psrldq_xmm },
2946
    [16 + 6] = MMX_OP2(psllq),
2947
    [16 + 7] = { NULL, gen_helper_pslldq_xmm },
2948
};
2949

    
2950
static void *sse_op_table3[4 * 3] = {
2951
    gen_helper_cvtsi2ss,
2952
    gen_helper_cvtsi2sd,
2953
    X86_64_ONLY(gen_helper_cvtsq2ss),
2954
    X86_64_ONLY(gen_helper_cvtsq2sd),
2955

    
2956
    gen_helper_cvttss2si,
2957
    gen_helper_cvttsd2si,
2958
    X86_64_ONLY(gen_helper_cvttss2sq),
2959
    X86_64_ONLY(gen_helper_cvttsd2sq),
2960

    
2961
    gen_helper_cvtss2si,
2962
    gen_helper_cvtsd2si,
2963
    X86_64_ONLY(gen_helper_cvtss2sq),
2964
    X86_64_ONLY(gen_helper_cvtsd2sq),
2965
};
2966

    
2967
static void *sse_op_table4[8][4] = {
2968
    SSE_FOP(cmpeq),
2969
    SSE_FOP(cmplt),
2970
    SSE_FOP(cmple),
2971
    SSE_FOP(cmpunord),
2972
    SSE_FOP(cmpneq),
2973
    SSE_FOP(cmpnlt),
2974
    SSE_FOP(cmpnle),
2975
    SSE_FOP(cmpord),
2976
};
2977

    
2978
static void *sse_op_table5[256] = {
2979
    [0x0c] = gen_helper_pi2fw,
2980
    [0x0d] = gen_helper_pi2fd,
2981
    [0x1c] = gen_helper_pf2iw,
2982
    [0x1d] = gen_helper_pf2id,
2983
    [0x8a] = gen_helper_pfnacc,
2984
    [0x8e] = gen_helper_pfpnacc,
2985
    [0x90] = gen_helper_pfcmpge,
2986
    [0x94] = gen_helper_pfmin,
2987
    [0x96] = gen_helper_pfrcp,
2988
    [0x97] = gen_helper_pfrsqrt,
2989
    [0x9a] = gen_helper_pfsub,
2990
    [0x9e] = gen_helper_pfadd,
2991
    [0xa0] = gen_helper_pfcmpgt,
2992
    [0xa4] = gen_helper_pfmax,
2993
    [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
2994
    [0xa7] = gen_helper_movq, /* pfrsqit1 */
2995
    [0xaa] = gen_helper_pfsubr,
2996
    [0xae] = gen_helper_pfacc,
2997
    [0xb0] = gen_helper_pfcmpeq,
2998
    [0xb4] = gen_helper_pfmul,
2999
    [0xb6] = gen_helper_movq, /* pfrcpit2 */
3000
    [0xb7] = gen_helper_pmulhrw_mmx,
3001
    [0xbb] = gen_helper_pswapd,
3002
    [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
3003
};
3004

    
3005
struct sse_op_helper_s {
3006
    void *op[2]; uint32_t ext_mask;
3007
};
3008
#define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
3009
#define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
3010
#define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
3011
#define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
3012
static struct sse_op_helper_s sse_op_table6[256] = {
3013
    [0x00] = SSSE3_OP(pshufb),
3014
    [0x01] = SSSE3_OP(phaddw),
3015
    [0x02] = SSSE3_OP(phaddd),
3016
    [0x03] = SSSE3_OP(phaddsw),
3017
    [0x04] = SSSE3_OP(pmaddubsw),
3018
    [0x05] = SSSE3_OP(phsubw),
3019
    [0x06] = SSSE3_OP(phsubd),
3020
    [0x07] = SSSE3_OP(phsubsw),
3021
    [0x08] = SSSE3_OP(psignb),
3022
    [0x09] = SSSE3_OP(psignw),
3023
    [0x0a] = SSSE3_OP(psignd),
3024
    [0x0b] = SSSE3_OP(pmulhrsw),
3025
    [0x10] = SSE41_OP(pblendvb),
3026
    [0x14] = SSE41_OP(blendvps),
3027
    [0x15] = SSE41_OP(blendvpd),
3028
    [0x17] = SSE41_OP(ptest),
3029
    [0x1c] = SSSE3_OP(pabsb),
3030
    [0x1d] = SSSE3_OP(pabsw),
3031
    [0x1e] = SSSE3_OP(pabsd),
3032
    [0x20] = SSE41_OP(pmovsxbw),
3033
    [0x21] = SSE41_OP(pmovsxbd),
3034
    [0x22] = SSE41_OP(pmovsxbq),
3035
    [0x23] = SSE41_OP(pmovsxwd),
3036
    [0x24] = SSE41_OP(pmovsxwq),
3037
    [0x25] = SSE41_OP(pmovsxdq),
3038
    [0x28] = SSE41_OP(pmuldq),
3039
    [0x29] = SSE41_OP(pcmpeqq),
3040
    [0x2a] = SSE41_SPECIAL, /* movntqda */
3041
    [0x2b] = SSE41_OP(packusdw),
3042
    [0x30] = SSE41_OP(pmovzxbw),
3043
    [0x31] = SSE41_OP(pmovzxbd),
3044
    [0x32] = SSE41_OP(pmovzxbq),
3045
    [0x33] = SSE41_OP(pmovzxwd),
3046
    [0x34] = SSE41_OP(pmovzxwq),
3047
    [0x35] = SSE41_OP(pmovzxdq),
3048
    [0x37] = SSE42_OP(pcmpgtq),
3049
    [0x38] = SSE41_OP(pminsb),
3050
    [0x39] = SSE41_OP(pminsd),
3051
    [0x3a] = SSE41_OP(pminuw),
3052
    [0x3b] = SSE41_OP(pminud),
3053
    [0x3c] = SSE41_OP(pmaxsb),
3054
    [0x3d] = SSE41_OP(pmaxsd),
3055
    [0x3e] = SSE41_OP(pmaxuw),
3056
    [0x3f] = SSE41_OP(pmaxud),
3057
    [0x40] = SSE41_OP(pmulld),
3058
    [0x41] = SSE41_OP(phminposuw),
3059
};
3060

    
3061
static struct sse_op_helper_s sse_op_table7[256] = {
3062
    [0x08] = SSE41_OP(roundps),
3063
    [0x09] = SSE41_OP(roundpd),
3064
    [0x0a] = SSE41_OP(roundss),
3065
    [0x0b] = SSE41_OP(roundsd),
3066
    [0x0c] = SSE41_OP(blendps),
3067
    [0x0d] = SSE41_OP(blendpd),
3068
    [0x0e] = SSE41_OP(pblendw),
3069
    [0x0f] = SSSE3_OP(palignr),
3070
    [0x14] = SSE41_SPECIAL, /* pextrb */
3071
    [0x15] = SSE41_SPECIAL, /* pextrw */
3072
    [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */
3073
    [0x17] = SSE41_SPECIAL, /* extractps */
3074
    [0x20] = SSE41_SPECIAL, /* pinsrb */
3075
    [0x21] = SSE41_SPECIAL, /* insertps */
3076
    [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */
3077
    [0x40] = SSE41_OP(dpps),
3078
    [0x41] = SSE41_OP(dppd),
3079
    [0x42] = SSE41_OP(mpsadbw),
3080
    [0x60] = SSE42_OP(pcmpestrm),
3081
    [0x61] = SSE42_OP(pcmpestri),
3082
    [0x62] = SSE42_OP(pcmpistrm),
3083
    [0x63] = SSE42_OP(pcmpistri),
3084
};
3085

    
3086
static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
3087
{
3088
    int b1, op1_offset, op2_offset, is_xmm, val, ot;
3089
    int modrm, mod, rm, reg, reg_addr, offset_addr;
3090
    void *sse_op2;
3091

    
3092
    b &= 0xff;
3093
    if (s->prefix & PREFIX_DATA)
3094
        b1 = 1;
3095
    else if (s->prefix & PREFIX_REPZ)
3096
        b1 = 2;
3097
    else if (s->prefix & PREFIX_REPNZ)
3098
        b1 = 3;
3099
    else
3100
        b1 = 0;
3101
    sse_op2 = sse_op_table1[b][b1];
3102
    if (!sse_op2)
3103
        goto illegal_op;
3104
    if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
3105
        is_xmm = 1;
3106
    } else {
3107
        if (b1 == 0) {
3108
            /* MMX case */
3109
            is_xmm = 0;
3110
        } else {
3111
            is_xmm = 1;
3112
        }
3113
    }
3114
    /* simple MMX/SSE operation */
3115
    if (s->flags & HF_TS_MASK) {
3116
        gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
3117
        return;
3118
    }
3119
    if (s->flags & HF_EM_MASK) {
3120
    illegal_op:
3121
        gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
3122
        return;
3123
    }
3124
    if (is_xmm && !(s->flags & HF_OSFXSR_MASK))
3125
        if ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))
3126
            goto illegal_op;
3127
    if (b == 0x0e) {
3128
        if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
3129
            goto illegal_op;
3130
        /* femms */
3131
        gen_helper_emms();
3132
        return;
3133
    }
3134
    if (b == 0x77) {
3135
        /* emms */
3136
        gen_helper_emms();
3137
        return;
3138
    }
3139
    /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3140
       the static cpu state) */
3141
    if (!is_xmm) {
3142
        gen_helper_enter_mmx();
3143
    }
3144

    
3145
    modrm = ldub_code(s->pc++);
3146
    reg = ((modrm >> 3) & 7);
3147
    if (is_xmm)
3148
        reg |= rex_r;
3149
    mod = (modrm >> 6) & 3;
3150
    if (sse_op2 == SSE_SPECIAL) {
3151
        b |= (b1 << 8);
3152
        switch(b) {
3153
        case 0x0e7: /* movntq */
3154
            if (mod == 3)
3155
                goto illegal_op;
3156
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3157
            gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
3158
            break;
3159
        case 0x1e7: /* movntdq */
3160
        case 0x02b: /* movntps */
3161
        case 0x12b: /* movntps */
3162
        case 0x3f0: /* lddqu */
3163
            if (mod == 3)
3164
                goto illegal_op;
3165
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3166
            gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3167
            break;
3168
        case 0x6e: /* movd mm, ea */
3169
#ifdef TARGET_X86_64
3170
            if (s->dflag == 2) {
3171
                gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
3172
                tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,fpregs[reg].mmx));
3173
            } else
3174
#endif
3175
            {
3176
                gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
3177
                tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
3178
                                 offsetof(CPUX86State,fpregs[reg].mmx));
3179
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3180
                gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32);
3181
            }
3182
            break;
3183
        case 0x16e: /* movd xmm, ea */
3184
#ifdef TARGET_X86_64
3185
            if (s->dflag == 2) {
3186
                gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
3187
                tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
3188
                                 offsetof(CPUX86State,xmm_regs[reg]));
3189
                gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T[0]);
3190
            } else
3191
#endif
3192
            {
3193
                gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
3194
                tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
3195
                                 offsetof(CPUX86State,xmm_regs[reg]));
3196
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3197
                gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32);
3198
            }
3199
            break;
3200
        case 0x6f: /* movq mm, ea */
3201
            if (mod != 3) {
3202
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3203
                gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
3204
            } else {
3205
                rm = (modrm & 7);
3206
                tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
3207
                               offsetof(CPUX86State,fpregs[rm].mmx));
3208
                tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
3209
                               offsetof(CPUX86State,fpregs[reg].mmx));
3210
            }
3211
            break;
3212
        case 0x010: /* movups */
3213
        case 0x110: /* movupd */
3214
        case 0x028: /* movaps */
3215
        case 0x128: /* movapd */
3216
        case 0x16f: /* movdqa xmm, ea */
3217
        case 0x26f: /* movdqu xmm, ea */
3218
            if (mod != 3) {
3219
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3220
                gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3221
            } else {
3222
                rm = (modrm & 7) | REX_B(s);
3223
                gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
3224
                            offsetof(CPUX86State,xmm_regs[rm]));
3225
            }
3226
            break;
3227
        case 0x210: /* movss xmm, ea */
3228
            if (mod != 3) {
3229
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3230
                gen_op_ld_T0_A0(OT_LONG + s->mem_index);
3231
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3232
                gen_op_movl_T0_0();
3233
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
3234
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
3235
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
3236
            } else {
3237
                rm = (modrm & 7) | REX_B(s);
3238
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
3239
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
3240
            }
3241
            break;
3242
        case 0x310: /* movsd xmm, ea */
3243
            if (mod != 3) {
3244
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3245
                gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3246
                gen_op_movl_T0_0();
3247
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
3248
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
3249
            } else {
3250
                rm = (modrm & 7) | REX_B(s);
3251
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3252
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3253
            }
3254
            break;
3255
        case 0x012: /* movlps */
3256
        case 0x112: /* movlpd */
3257
            if (mod != 3) {
3258
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3259
                gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3260
            } else {
3261
                /* movhlps */
3262
                rm = (modrm & 7) | REX_B(s);
3263
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3264
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
3265
            }
3266
            break;
3267
        case 0x212: /* movsldup */
3268
            if (mod != 3) {
3269
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3270
                gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3271
            } else {
3272
                rm = (modrm & 7) | REX_B(s);
3273
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
3274
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
3275
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
3276
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(2)));
3277
            }
3278
            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
3279
                        offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3280
            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
3281
                        offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
3282
            break;
3283
        case 0x312: /* movddup */
3284
            if (mod != 3) {
3285
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3286
                gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3287
            } else {
3288
                rm = (modrm & 7) | REX_B(s);
3289
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3290
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3291
            }
3292
            gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
3293
                        offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3294
            break;
3295
        case 0x016: /* movhps */
3296
        case 0x116: /* movhpd */
3297
            if (mod != 3) {
3298
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3299
                gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3300
            } else {
3301
                /* movlhps */
3302
                rm = (modrm & 7) | REX_B(s);
3303
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
3304
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3305
            }
3306
            break;
3307
        case 0x216: /* movshdup */
3308
            if (mod != 3) {
3309
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3310
                gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3311
            } else {
3312
                rm = (modrm & 7) | REX_B(s);
3313
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
3314
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(1)));
3315
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
3316
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(3)));
3317
            }
3318
            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
3319
                        offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
3320
            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
3321
                        offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
3322
            break;
3323
        case 0x7e: /* movd ea, mm */
3324
#ifdef TARGET_X86_64
3325
            if (s->dflag == 2) {
3326
                tcg_gen_ld_i64(cpu_T[0], cpu_env, 
3327
                               offsetof(CPUX86State,fpregs[reg].mmx));
3328
                gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1);
3329
            } else
3330
#endif
3331
            {
3332
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
3333
                                 offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0)));
3334
                gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
3335
            }
3336
            break;
3337
        case 0x17e: /* movd ea, xmm */
3338
#ifdef TARGET_X86_64
3339
            if (s->dflag == 2) {
3340
                tcg_gen_ld_i64(cpu_T[0], cpu_env, 
3341
                               offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3342
                gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1);
3343
            } else
3344
#endif
3345
            {
3346
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
3347
                                 offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3348
                gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
3349
            }
3350
            break;
3351
        case 0x27e: /* movq xmm, ea */
3352
            if (mod != 3) {
3353
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3354
                gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3355
            } else {
3356
                rm = (modrm & 7) | REX_B(s);
3357
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3358
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3359
            }
3360
            gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3361
            break;
3362
        case 0x7f: /* movq ea, mm */
3363
            if (mod != 3) {
3364
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3365
                gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
3366
            } else {
3367
                rm = (modrm & 7);
3368
                gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
3369
                            offsetof(CPUX86State,fpregs[reg].mmx));
3370
            }
3371
            break;
3372
        case 0x011: /* movups */
3373
        case 0x111: /* movupd */
3374
        case 0x029: /* movaps */
3375
        case 0x129: /* movapd */
3376
        case 0x17f: /* movdqa ea, xmm */
3377
        case 0x27f: /* movdqu ea, xmm */
3378
            if (mod != 3) {
3379
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3380
                gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3381
            } else {
3382
                rm = (modrm & 7) | REX_B(s);
3383
                gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
3384
                            offsetof(CPUX86State,xmm_regs[reg]));
3385
            }
3386
            break;
3387
        case 0x211: /* movss ea, xmm */
3388
            if (mod != 3) {
3389
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3390
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3391
                gen_op_st_T0_A0(OT_LONG + s->mem_index);
3392
            } else {
3393
                rm = (modrm & 7) | REX_B(s);
3394
                gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)),
3395
                            offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3396
            }
3397
            break;
3398
        case 0x311: /* movsd ea, xmm */
3399
            if (mod != 3) {
3400
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3401
                gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3402
            } else {
3403
                rm = (modrm & 7) | REX_B(s);
3404
                gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
3405
                            offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3406
            }
3407
            break;
3408
        case 0x013: /* movlps */
3409
        case 0x113: /* movlpd */
3410
            if (mod != 3) {
3411
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3412
                gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3413
            } else {
3414
                goto illegal_op;
3415
            }
3416
            break;
3417
        case 0x017: /* movhps */
3418
        case 0x117: /* movhpd */
3419
            if (mod != 3) {
3420
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3421
                gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3422
            } else {
3423
                goto illegal_op;
3424
            }
3425
            break;
3426
        case 0x71: /* shift mm, im */
3427
        case 0x72:
3428
        case 0x73:
3429
        case 0x171: /* shift xmm, im */
3430
        case 0x172:
3431
        case 0x173:
3432
            val = ldub_code(s->pc++);
3433
            if (is_xmm) {
3434
                gen_op_movl_T0_im(val);
3435
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
3436
                gen_op_movl_T0_0();
3437
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(1)));
3438
                op1_offset = offsetof(CPUX86State,xmm_t0);
3439
            } else {
3440
                gen_op_movl_T0_im(val);
3441
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0)));
3442
                gen_op_movl_T0_0();
3443
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1)));
3444
                op1_offset = offsetof(CPUX86State,mmx_t0);
3445
            }
3446
            sse_op2 = sse_op_table2[((b - 1) & 3) * 8 + (((modrm >> 3)) & 7)][b1];
3447
            if (!sse_op2)
3448
                goto illegal_op;
3449
            if (is_xmm) {
3450
                rm = (modrm & 7) | REX_B(s);
3451
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3452
            } else {
3453
                rm = (modrm & 7);
3454
                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3455
            }
3456
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3457
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset);
3458
            ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
3459
            break;
3460
        case 0x050: /* movmskps */
3461
            rm = (modrm & 7) | REX_B(s);
3462
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
3463
                             offsetof(CPUX86State,xmm_regs[rm]));
3464
            gen_helper_movmskps(cpu_tmp2_i32, cpu_ptr0);
3465
            tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3466
            gen_op_mov_reg_T0(OT_LONG, reg);
3467
            break;
3468
        case 0x150: /* movmskpd */
3469
            rm = (modrm & 7) | REX_B(s);
3470
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
3471
                             offsetof(CPUX86State,xmm_regs[rm]));
3472
            gen_helper_movmskpd(cpu_tmp2_i32, cpu_ptr0);
3473
            tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3474
            gen_op_mov_reg_T0(OT_LONG, reg);
3475
            break;
3476
        case 0x02a: /* cvtpi2ps */
3477
        case 0x12a: /* cvtpi2pd */
3478
            gen_helper_enter_mmx();
3479
            if (mod != 3) {
3480
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3481
                op2_offset = offsetof(CPUX86State,mmx_t0);
3482
                gen_ldq_env_A0(s->mem_index, op2_offset);
3483
            } else {
3484
                rm = (modrm & 7);
3485
                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3486
            }
3487
            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3488
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3489
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3490
            switch(b >> 8) {
3491
            case 0x0:
3492
                gen_helper_cvtpi2ps(cpu_ptr0, cpu_ptr1);
3493
                break;
3494
            default:
3495
            case 0x1:
3496
                gen_helper_cvtpi2pd(cpu_ptr0, cpu_ptr1);
3497
                break;
3498
            }
3499
            break;
3500
        case 0x22a: /* cvtsi2ss */
3501
        case 0x32a: /* cvtsi2sd */
3502
            ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3503
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3504
            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3505
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3506
            sse_op2 = sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2)];
3507
            if (ot == OT_LONG) {
3508
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3509
                ((void (*)(TCGv_ptr, TCGv_i32))sse_op2)(cpu_ptr0, cpu_tmp2_i32);
3510
            } else {
3511
                ((void (*)(TCGv_ptr, TCGv))sse_op2)(cpu_ptr0, cpu_T[0]);
3512
            }
3513
            break;
3514
        case 0x02c: /* cvttps2pi */
3515
        case 0x12c: /* cvttpd2pi */
3516
        case 0x02d: /* cvtps2pi */
3517
        case 0x12d: /* cvtpd2pi */
3518
            gen_helper_enter_mmx();
3519
            if (mod != 3) {
3520
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3521
                op2_offset = offsetof(CPUX86State,xmm_t0);
3522
                gen_ldo_env_A0(s->mem_index, op2_offset);
3523
            } else {
3524
                rm = (modrm & 7) | REX_B(s);
3525
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3526
            }
3527
            op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
3528
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3529
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3530
            switch(b) {
3531
            case 0x02c:
3532
                gen_helper_cvttps2pi(cpu_ptr0, cpu_ptr1);
3533
                break;
3534
            case 0x12c:
3535
                gen_helper_cvttpd2pi(cpu_ptr0, cpu_ptr1);
3536
                break;
3537
            case 0x02d:
3538
                gen_helper_cvtps2pi(cpu_ptr0, cpu_ptr1);
3539
                break;
3540
            case 0x12d:
3541
                gen_helper_cvtpd2pi(cpu_ptr0, cpu_ptr1);
3542
                break;
3543
            }
3544
            break;
3545
        case 0x22c: /* cvttss2si */
3546
        case 0x32c: /* cvttsd2si */
3547
        case 0x22d: /* cvtss2si */
3548
        case 0x32d: /* cvtsd2si */
3549
            ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3550
            if (mod != 3) {
3551
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3552
                if ((b >> 8) & 1) {
3553
                    gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_Q(0)));
3554
                } else {
3555
                    gen_op_ld_T0_A0(OT_LONG + s->mem_index);
3556
                    tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
3557
                }
3558
                op2_offset = offsetof(CPUX86State,xmm_t0);
3559
            } else {
3560
                rm = (modrm & 7) | REX_B(s);
3561
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3562
            }
3563
            sse_op2 = sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2) + 4 +
3564
                                    (b & 1) * 4];
3565
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3566
            if (ot == OT_LONG) {
3567
                ((void (*)(TCGv_i32, TCGv_ptr))sse_op2)(cpu_tmp2_i32, cpu_ptr0);
3568
                tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3569
            } else {
3570
                ((void (*)(TCGv, TCGv_ptr))sse_op2)(cpu_T[0], cpu_ptr0);
3571
            }
3572
            gen_op_mov_reg_T0(ot, reg);
3573
            break;
3574
        case 0xc4: /* pinsrw */
3575
        case 0x1c4:
3576
            s->rip_offset = 1;
3577
            gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
3578
            val = ldub_code(s->pc++);
3579
            if (b1) {
3580
                val &= 7;
3581
                tcg_gen_st16_tl(cpu_T[0], cpu_env,
3582
                                offsetof(CPUX86State,xmm_regs[reg].XMM_W(val)));
3583
            } else {
3584
                val &= 3;
3585
                tcg_gen_st16_tl(cpu_T[0], cpu_env,
3586
                                offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val)));
3587
            }
3588
            break;
3589
        case 0xc5: /* pextrw */
3590
        case 0x1c5:
3591
            if (mod != 3)
3592
                goto illegal_op;
3593
            ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3594
            val = ldub_code(s->pc++);
3595
            if (b1) {
3596
                val &= 7;
3597
                rm = (modrm & 7) | REX_B(s);
3598
                tcg_gen_ld16u_tl(cpu_T[0], cpu_env,
3599
                                 offsetof(CPUX86State,xmm_regs[rm].XMM_W(val)));
3600
            } else {
3601
                val &= 3;
3602
                rm = (modrm & 7);
3603
                tcg_gen_ld16u_tl(cpu_T[0], cpu_env,
3604
                                offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
3605
            }
3606
            reg = ((modrm >> 3) & 7) | rex_r;
3607
            gen_op_mov_reg_T0(ot, reg);
3608
            break;
3609
        case 0x1d6: /* movq ea, xmm */
3610
            if (mod != 3) {
3611
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3612
                gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3613
            } else {
3614
                rm = (modrm & 7) | REX_B(s);
3615
                gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
3616
                            offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3617
                gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
3618
            }
3619
            break;
3620
        case 0x2d6: /* movq2dq */
3621
            gen_helper_enter_mmx();
3622
            rm = (modrm & 7);
3623
            gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3624
                        offsetof(CPUX86State,fpregs[rm].mmx));
3625
            gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3626
            break;
3627
        case 0x3d6: /* movdq2q */
3628
            gen_helper_enter_mmx();
3629
            rm = (modrm & 7) | REX_B(s);
3630
            gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
3631
                        offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3632
            break;
3633
        case 0xd7: /* pmovmskb */
3634
        case 0x1d7:
3635
            if (mod != 3)
3636
                goto illegal_op;
3637
            if (b1) {
3638
                rm = (modrm & 7) | REX_B(s);
3639
                tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm]));
3640
                gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_ptr0);
3641
            } else {
3642
                rm = (modrm & 7);
3643
                tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx));
3644
                gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_ptr0);
3645
            }
3646
            tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3647
            reg = ((modrm >> 3) & 7) | rex_r;
3648
            gen_op_mov_reg_T0(OT_LONG, reg);
3649
            break;
3650
        case 0x138:
3651
            if (s->prefix & PREFIX_REPNZ)
3652
                goto crc32;
3653
        case 0x038:
3654
            b = modrm;
3655
            modrm = ldub_code(s->pc++);
3656
            rm = modrm & 7;
3657
            reg = ((modrm >> 3) & 7) | rex_r;
3658
            mod = (modrm >> 6) & 3;
3659

    
3660
            sse_op2 = sse_op_table6[b].op[b1];
3661
            if (!sse_op2)
3662
                goto illegal_op;
3663
            if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
3664
                goto illegal_op;
3665

    
3666
            if (b1) {
3667
                op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3668
                if (mod == 3) {
3669
                    op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
3670
                } else {
3671
                    op2_offset = offsetof(CPUX86State,xmm_t0);
3672
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3673
                    switch (b) {
3674
                    case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3675
                    case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3676
                    case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3677
                        gen_ldq_env_A0(s->mem_index, op2_offset +
3678
                                        offsetof(XMMReg, XMM_Q(0)));
3679
                        break;
3680
                    case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3681
                    case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3682
                        tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
3683
                                          (s->mem_index >> 2) - 1);
3684
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
3685
                        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset +
3686
                                        offsetof(XMMReg, XMM_L(0)));
3687
                        break;
3688
                    case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3689
                        tcg_gen_qemu_ld16u(cpu_tmp0, cpu_A0,
3690
                                          (s->mem_index >> 2) - 1);
3691
                        tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset +
3692
                                        offsetof(XMMReg, XMM_W(0)));
3693
                        break;
3694
                    case 0x2a:            /* movntqda */
3695
                        gen_ldo_env_A0(s->mem_index, op1_offset);
3696
                        return;
3697
                    default:
3698
                        gen_ldo_env_A0(s->mem_index, op2_offset);
3699
                    }
3700
                }
3701
            } else {
3702
                op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3703
                if (mod == 3) {
3704
                    op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3705
                } else {
3706
                    op2_offset = offsetof(CPUX86State,mmx_t0);
3707
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3708
                    gen_ldq_env_A0(s->mem_index, op2_offset);
3709
                }
3710
            }
3711
            if (sse_op2 == SSE_SPECIAL)
3712
                goto illegal_op;
3713

    
3714
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3715
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3716
            ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
3717

    
3718
            if (b == 0x17)
3719
                s->cc_op = CC_OP_EFLAGS;
3720
            break;
3721
        case 0x338: /* crc32 */
3722
        crc32:
3723
            b = modrm;
3724
            modrm = ldub_code(s->pc++);
3725
            reg = ((modrm >> 3) & 7) | rex_r;
3726

    
3727
            if (b != 0xf0 && b != 0xf1)
3728
                goto illegal_op;
3729
            if (!(s->cpuid_ext_features & CPUID_EXT_SSE42))
3730
                goto illegal_op;
3731

    
3732
            if (b == 0xf0)
3733
                ot = OT_BYTE;
3734
            else if (b == 0xf1 && s->dflag != 2)
3735
                if (s->prefix & PREFIX_DATA)
3736
                    ot = OT_WORD;
3737
                else
3738
                    ot = OT_LONG;
3739
            else
3740
                ot = OT_QUAD;
3741

    
3742
            gen_op_mov_TN_reg(OT_LONG, 0, reg);
3743
            tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3744
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3745
            gen_helper_crc32(cpu_T[0], cpu_tmp2_i32,
3746
                             cpu_T[0], tcg_const_i32(8 << ot));
3747

    
3748
            ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3749
            gen_op_mov_reg_T0(ot, reg);
3750
            break;
3751
        case 0x03a:
3752
        case 0x13a:
3753
            b = modrm;
3754
            modrm = ldub_code(s->pc++);
3755
            rm = modrm & 7;
3756
            reg = ((modrm >> 3) & 7) | rex_r;
3757
            mod = (modrm >> 6) & 3;
3758

    
3759
            sse_op2 = sse_op_table7[b].op[b1];
3760
            if (!sse_op2)
3761
                goto illegal_op;
3762
            if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
3763
                goto illegal_op;
3764

    
3765
            if (sse_op2 == SSE_SPECIAL) {
3766
                ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3767
                rm = (modrm & 7) | REX_B(s);
3768
                if (mod != 3)
3769
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3770
                reg = ((modrm >> 3) & 7) | rex_r;
3771
                val = ldub_code(s->pc++);
3772
                switch (b) {
3773
                case 0x14: /* pextrb */
3774
                    tcg_gen_ld8u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
3775
                                            xmm_regs[reg].XMM_B(val & 15)));
3776
                    if (mod == 3)
3777
                        gen_op_mov_reg_T0(ot, rm);
3778
                    else
3779
                        tcg_gen_qemu_st8(cpu_T[0], cpu_A0,
3780
                                        (s->mem_index >> 2) - 1);
3781
                    break;
3782
                case 0x15: /* pextrw */
3783
                    tcg_gen_ld16u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
3784
                                            xmm_regs[reg].XMM_W(val & 7)));
3785
                    if (mod == 3)
3786
                        gen_op_mov_reg_T0(ot, rm);
3787
                    else
3788
                        tcg_gen_qemu_st16(cpu_T[0], cpu_A0,
3789
                                        (s->mem_index >> 2) - 1);
3790
                    break;
3791
                case 0x16:
3792
                    if (ot == OT_LONG) { /* pextrd */
3793
                        tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
3794
                                        offsetof(CPUX86State,
3795
                                                xmm_regs[reg].XMM_L(val & 3)));
3796
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3797
                        if (mod == 3)
3798
                            gen_op_mov_reg_v(ot, rm, cpu_T[0]);
3799
                        else
3800
                            tcg_gen_qemu_st32(cpu_T[0], cpu_A0,
3801
                                            (s->mem_index >> 2) - 1);
3802
                    } else { /* pextrq */
3803
#ifdef TARGET_X86_64
3804
                        tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
3805
                                        offsetof(CPUX86State,
3806
                                                xmm_regs[reg].XMM_Q(val & 1)));
3807
                        if (mod == 3)
3808
                            gen_op_mov_reg_v(ot, rm, cpu_tmp1_i64);
3809
                        else
3810
                            tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0,
3811
                                            (s->mem_index >> 2) - 1);
3812
#else
3813
                        goto illegal_op;
3814
#endif
3815
                    }
3816
                    break;
3817
                case 0x17: /* extractps */
3818
                    tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
3819
                                            xmm_regs[reg].XMM_L(val & 3)));
3820
                    if (mod == 3)
3821
                        gen_op_mov_reg_T0(ot, rm);
3822
                    else
3823
                        tcg_gen_qemu_st32(cpu_T[0], cpu_A0,
3824
                                        (s->mem_index >> 2) - 1);
3825
                    break;
3826
                case 0x20: /* pinsrb */
3827
                    if (mod == 3)
3828
                        gen_op_mov_TN_reg(OT_LONG, 0, rm);
3829
                    else
3830
                        tcg_gen_qemu_ld8u(cpu_tmp0, cpu_A0,
3831
                                        (s->mem_index >> 2) - 1);
3832
                    tcg_gen_st8_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State,
3833
                                            xmm_regs[reg].XMM_B(val & 15)));
3834
                    break;
3835
                case 0x21: /* insertps */
3836
                    if (mod == 3) {
3837
                        tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
3838
                                        offsetof(CPUX86State,xmm_regs[rm]
3839
                                                .XMM_L((val >> 6) & 3)));
3840
                    } else {
3841
                        tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
3842
                                        (s->mem_index >> 2) - 1);
3843
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
3844
                    }
3845
                    tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
3846
                                    offsetof(CPUX86State,xmm_regs[reg]
3847
                                            .XMM_L((val >> 4) & 3)));
3848
                    if ((val >> 0) & 1)
3849
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
3850
                                        cpu_env, offsetof(CPUX86State,
3851
                                                xmm_regs[reg].XMM_L(0)));
3852
                    if ((val >> 1) & 1)
3853
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
3854
                                        cpu_env, offsetof(CPUX86State,
3855
                                                xmm_regs[reg].XMM_L(1)));
3856
                    if ((val >> 2) & 1)
3857
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
3858
                                        cpu_env, offsetof(CPUX86State,
3859
                                                xmm_regs[reg].XMM_L(2)));
3860
                    if ((val >> 3) & 1)
3861
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
3862
                                        cpu_env, offsetof(CPUX86State,
3863
                                                xmm_regs[reg].XMM_L(3)));
3864
                    break;
3865
                case 0x22:
3866
                    if (ot == OT_LONG) { /* pinsrd */
3867
                        if (mod == 3)
3868
                            gen_op_mov_v_reg(ot, cpu_tmp0, rm);
3869
                        else
3870
                            tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
3871
                                            (s->mem_index >> 2) - 1);
3872
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
3873
                        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
3874
                                        offsetof(CPUX86State,
3875
                                                xmm_regs[reg].XMM_L(val & 3)));
3876
                    } else { /* pinsrq */
3877
#ifdef TARGET_X86_64
3878
                        if (mod == 3)
3879
                            gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);
3880
                        else
3881
                            tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0,
3882
                                            (s->mem_index >> 2) - 1);
3883
                        tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
3884
                                        offsetof(CPUX86State,
3885
                                                xmm_regs[reg].XMM_Q(val & 1)));
3886
#else
3887
                        goto illegal_op;
3888
#endif
3889
                    }
3890
                    break;
3891
                }
3892
                return;
3893
            }
3894

    
3895
            if (b1) {
3896
                op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3897
                if (mod == 3) {
3898
                    op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
3899
                } else {
3900
                    op2_offset = offsetof(CPUX86State,xmm_t0);
3901
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3902
                    gen_ldo_env_A0(s->mem_index, op2_offset);
3903
                }
3904
            } else {
3905
                op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3906
                if (mod == 3) {
3907
                    op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3908
                } else {
3909
                    op2_offset = offsetof(CPUX86State,mmx_t0);
3910
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3911
                    gen_ldq_env_A0(s->mem_index, op2_offset);
3912
                }
3913
            }
3914
            val = ldub_code(s->pc++);
3915

    
3916
            if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
3917
                s->cc_op = CC_OP_EFLAGS;
3918

    
3919
                if (s->dflag == 2)
3920
                    /* The helper must use entire 64-bit gp registers */
3921
                    val |= 1 << 8;
3922
            }
3923

    
3924
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3925
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3926
            ((void (*)(TCGv_ptr, TCGv_ptr, TCGv_i32))sse_op2)(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
3927
            break;
3928
        default:
3929
            goto illegal_op;
3930
        }
3931
    } else {
3932
        /* generic MMX or SSE operation */
3933
        switch(b) {
3934
        case 0x70: /* pshufx insn */
3935
        case 0xc6: /* pshufx insn */
3936
        case 0xc2: /* compare insns */
3937
            s->rip_offset = 1;
3938
            break;
3939
        default:
3940
            break;
3941
        }
3942
        if (is_xmm) {
3943
            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3944
            if (mod != 3) {
3945
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3946
                op2_offset = offsetof(CPUX86State,xmm_t0);
3947
                if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f && b != 0x5b) ||
3948
                                b == 0xc2)) {
3949
                    /* specific case for SSE single instructions */
3950
                    if (b1 == 2) {
3951
                        /* 32 bit access */
3952
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
3953
                        tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
3954
                    } else {
3955
                        /* 64 bit access */
3956
                        gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_D(0)));
3957
                    }
3958
                } else {
3959
                    gen_ldo_env_A0(s->mem_index, op2_offset);
3960
                }
3961
            } else {
3962
                rm = (modrm & 7) | REX_B(s);
3963
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3964
            }
3965
        } else {
3966
            op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3967
            if (mod != 3) {
3968
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3969
                op2_offset = offsetof(CPUX86State,mmx_t0);
3970
                gen_ldq_env_A0(s->mem_index, op2_offset);
3971
            } else {
3972
                rm = (modrm & 7);
3973
                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3974
            }
3975
        }
3976
        switch(b) {
3977
        case 0x0f: /* 3DNow! data insns */
3978
            if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
3979
                goto illegal_op;
3980
            val = ldub_code(s->pc++);
3981
            sse_op2 = sse_op_table5[val];
3982
            if (!sse_op2)
3983
                goto illegal_op;
3984
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3985
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3986
            ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
3987
            break;
3988
        case 0x70: /* pshufx insn */
3989
        case 0xc6: /* pshufx insn */
3990
            val = ldub_code(s->pc++);
3991
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3992
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3993
            ((void (*)(TCGv_ptr, TCGv_ptr, TCGv_i32))sse_op2)(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
3994
            break;
3995
        case 0xc2:
3996
            /* compare insns */
3997
            val = ldub_code(s->pc++);
3998
            if (val >= 8)
3999
                goto illegal_op;
4000
            sse_op2 = sse_op_table4[val][b1];
4001
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4002
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4003
            ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
4004
            break;
4005
        case 0xf7:
4006
            /* maskmov : we must prepare A0 */
4007
            if (mod != 3)
4008
                goto illegal_op;
4009
#ifdef TARGET_X86_64
4010
            if (s->aflag == 2) {
4011
                gen_op_movq_A0_reg(R_EDI);
4012
            } else
4013
#endif
4014
            {
4015
                gen_op_movl_A0_reg(R_EDI);
4016
                if (s->aflag == 0)
4017
                    gen_op_andl_A0_ffff();
4018
            }
4019
            gen_add_A0_ds_seg(s);
4020

    
4021
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4022
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4023
            ((void (*)(TCGv_ptr, TCGv_ptr, TCGv))sse_op2)(cpu_ptr0, cpu_ptr1, cpu_A0);
4024
            break;
4025
        default:
4026
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4027
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4028
            ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
4029
            break;
4030
        }
4031
        if (b == 0x2e || b == 0x2f) {
4032
            s->cc_op = CC_OP_EFLAGS;
4033
        }
4034
    }
4035
}
4036

    
4037
/* convert one instruction. s->is_jmp is set if the translation must
4038
   be stopped. Return the next pc value */
4039
static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
4040
{
4041
    int b, prefixes, aflag, dflag;
4042
    int shift, ot;
4043
    int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
4044
    target_ulong next_eip, tval;
4045
    int rex_w, rex_r;
4046

    
4047
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
4048
        tcg_gen_debug_insn_start(pc_start);
4049
    s->pc = pc_start;
4050
    prefixes = 0;
4051
    aflag = s->code32;
4052
    dflag = s->code32;
4053
    s->override = -1;
4054
    rex_w = -1;
4055
    rex_r = 0;
4056
#ifdef TARGET_X86_64
4057
    s->rex_x = 0;
4058
    s->rex_b = 0;
4059
    x86_64_hregs = 0;
4060
#endif
4061
    s->rip_offset = 0; /* for relative ip address */
4062
 next_byte:
4063
    b = ldub_code(s->pc);
4064
    s->pc++;
4065
    /* check prefixes */
4066
#ifdef TARGET_X86_64
4067
    if (CODE64(s)) {
4068
        switch (b) {
4069
        case 0xf3:
4070
            prefixes |= PREFIX_REPZ;
4071
            goto next_byte;
4072
        case 0xf2:
4073
            prefixes |= PREFIX_REPNZ;
4074
            goto next_byte;
4075
        case 0xf0:
4076
            prefixes |= PREFIX_LOCK;
4077
            goto next_byte;
4078
        case 0x2e:
4079
            s->override = R_CS;
4080
            goto next_byte;
4081
        case 0x36:
4082
            s->override = R_SS;
4083
            goto next_byte;
4084
        case 0x3e:
4085
            s->override = R_DS;
4086
            goto next_byte;
4087
        case 0x26:
4088
            s->override = R_ES;
4089
            goto next_byte;
4090
        case 0x64:
4091
            s->override = R_FS;
4092
            goto next_byte;
4093
        case 0x65:
4094
            s->override = R_GS;
4095
            goto next_byte;
4096
        case 0x66:
4097
            prefixes |= PREFIX_DATA;
4098
            goto next_byte;
4099
        case 0x67:
4100
            prefixes |= PREFIX_ADR;
4101
            goto next_byte;
4102
        case 0x40 ... 0x4f:
4103
            /* REX prefix */
4104
            rex_w = (b >> 3) & 1;
4105
            rex_r = (b & 0x4) << 1;
4106
            s->rex_x = (b & 0x2) << 2;
4107
            REX_B(s) = (b & 0x1) << 3;
4108
            x86_64_hregs = 1; /* select uniform byte register addressing */
4109
            goto next_byte;
4110
        }
4111
        if (rex_w == 1) {
4112
            /* 0x66 is ignored if rex.w is set */
4113
            dflag = 2;
4114
        } else {
4115
            if (prefixes & PREFIX_DATA)
4116
                dflag ^= 1;
4117
        }
4118
        if (!(prefixes & PREFIX_ADR))
4119
            aflag = 2;
4120
    } else
4121
#endif
4122
    {
4123
        switch (b) {
4124
        case 0xf3:
4125
            prefixes |= PREFIX_REPZ;
4126
            goto next_byte;
4127
        case 0xf2:
4128
            prefixes |= PREFIX_REPNZ;
4129
            goto next_byte;
4130
        case 0xf0:
4131
            prefixes |= PREFIX_LOCK;
4132
            goto next_byte;
4133
        case 0x2e:
4134
            s->override = R_CS;
4135
            goto next_byte;
4136
        case 0x36:
4137
            s->override = R_SS;
4138
            goto next_byte;
4139
        case 0x3e:
4140
            s->override = R_DS;
4141
            goto next_byte;
4142
        case 0x26:
4143
            s->override = R_ES;
4144
            goto next_byte;
4145
        case 0x64:
4146
            s->override = R_FS;
4147
            goto next_byte;
4148
        case 0x65:
4149
            s->override = R_GS;
4150
            goto next_byte;
4151
        case 0x66:
4152
            prefixes |= PREFIX_DATA;
4153
            goto next_byte;
4154
        case 0x67:
4155
            prefixes |= PREFIX_ADR;
4156
            goto next_byte;
4157
        }
4158
        if (prefixes & PREFIX_DATA)
4159
            dflag ^= 1;
4160
        if (prefixes & PREFIX_ADR)
4161
            aflag ^= 1;
4162
    }
4163

    
4164
    s->prefix = prefixes;
4165
    s->aflag = aflag;
4166
    s->dflag = dflag;
4167

    
4168
    /* lock generation */
4169
    if (prefixes & PREFIX_LOCK)
4170
        gen_helper_lock();
4171

    
4172
    /* now check op code */
4173
 reswitch:
4174
    switch(b) {
4175
    case 0x0f:
4176
        /**************************/
4177
        /* extended op code */
4178
        b = ldub_code(s->pc++) | 0x100;
4179
        goto reswitch;
4180

    
4181
        /**************************/
4182
        /* arith & logic */
4183
    case 0x00 ... 0x05:
4184
    case 0x08 ... 0x0d:
4185
    case 0x10 ... 0x15:
4186
    case 0x18 ... 0x1d:
4187
    case 0x20 ... 0x25:
4188
    case 0x28 ... 0x2d:
4189
    case 0x30 ... 0x35:
4190
    case 0x38 ... 0x3d:
4191
        {
4192
            int op, f, val;
4193
            op = (b >> 3) & 7;
4194
            f = (b >> 1) & 3;
4195

    
4196
            if ((b & 1) == 0)
4197
                ot = OT_BYTE;
4198
            else
4199
                ot = dflag + OT_WORD;
4200

    
4201
            switch(f) {
4202
            case 0: /* OP Ev, Gv */
4203
                modrm = ldub_code(s->pc++);
4204
                reg = ((modrm >> 3) & 7) | rex_r;
4205
                mod = (modrm >> 6) & 3;
4206
                rm = (modrm & 7) | REX_B(s);
4207
                if (mod != 3) {
4208
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4209
                    opreg = OR_TMP0;
4210
                } else if (op == OP_XORL && rm == reg) {
4211
                xor_zero:
4212
                    /* xor reg, reg optimisation */
4213
                    gen_op_movl_T0_0();
4214
                    s->cc_op = CC_OP_LOGICB + ot;
4215
                    gen_op_mov_reg_T0(ot, reg);
4216
                    gen_op_update1_cc();
4217
                    break;
4218
                } else {
4219
                    opreg = rm;
4220
                }
4221
                gen_op_mov_TN_reg(ot, 1, reg);
4222
                gen_op(s, op, ot, opreg);
4223
                break;
4224
            case 1: /* OP Gv, Ev */
4225
                modrm = ldub_code(s->pc++);
4226
                mod = (modrm >> 6) & 3;
4227
                reg = ((modrm >> 3) & 7) | rex_r;
4228
                rm = (modrm & 7) | REX_B(s);
4229
                if (mod != 3) {
4230
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4231
                    gen_op_ld_T1_A0(ot + s->mem_index);
4232
                } else if (op == OP_XORL && rm == reg) {
4233
                    goto xor_zero;
4234
                } else {
4235
                    gen_op_mov_TN_reg(ot, 1, rm);
4236
                }
4237
                gen_op(s, op, ot, reg);
4238
                break;
4239
            case 2: /* OP A, Iv */
4240
                val = insn_get(s, ot);
4241
                gen_op_movl_T1_im(val);
4242
                gen_op(s, op, ot, OR_EAX);
4243
                break;
4244
            }
4245
        }
4246
        break;
4247

    
4248
    case 0x82:
4249
        if (CODE64(s))
4250
            goto illegal_op;
4251
    case 0x80: /* GRP1 */
4252
    case 0x81:
4253
    case 0x83:
4254
        {
4255
            int val;
4256

    
4257
            if ((b & 1) == 0)
4258
                ot = OT_BYTE;
4259
            else
4260
                ot = dflag + OT_WORD;
4261

    
4262
            modrm = ldub_code(s->pc++);
4263
            mod = (modrm >> 6) & 3;
4264
            rm = (modrm & 7) | REX_B(s);
4265
            op = (modrm >> 3) & 7;
4266

    
4267
            if (mod != 3) {
4268
                if (b == 0x83)
4269
                    s->rip_offset = 1;
4270
                else
4271
                    s->rip_offset = insn_const_size(ot);
4272
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4273
                opreg = OR_TMP0;
4274
            } else {
4275
                opreg = rm;
4276
            }
4277

    
4278
            switch(b) {
4279
            default:
4280
            case 0x80:
4281
            case 0x81:
4282
            case 0x82:
4283
                val = insn_get(s, ot);
4284
                break;
4285
            case 0x83:
4286
                val = (int8_t)insn_get(s, OT_BYTE);
4287
                break;
4288
            }
4289
            gen_op_movl_T1_im(val);
4290
            gen_op(s, op, ot, opreg);
4291
        }
4292
        break;
4293

    
4294
        /**************************/
4295
        /* inc, dec, and other misc arith */
4296
    case 0x40 ... 0x47: /* inc Gv */
4297
        ot = dflag ? OT_LONG : OT_WORD;
4298
        gen_inc(s, ot, OR_EAX + (b & 7), 1);
4299
        break;
4300
    case 0x48 ... 0x4f: /* dec Gv */
4301
        ot = dflag ? OT_LONG : OT_WORD;
4302
        gen_inc(s, ot, OR_EAX + (b & 7), -1);
4303
        break;
4304
    case 0xf6: /* GRP3 */
4305
    case 0xf7:
4306
        if ((b & 1) == 0)
4307
            ot = OT_BYTE;
4308
        else
4309
            ot = dflag + OT_WORD;
4310

    
4311
        modrm = ldub_code(s->pc++);
4312
        mod = (modrm >> 6) & 3;
4313
        rm = (modrm & 7) | REX_B(s);
4314
        op = (modrm >> 3) & 7;
4315
        if (mod != 3) {
4316
            if (op == 0)
4317
                s->rip_offset = insn_const_size(ot);
4318
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4319
            gen_op_ld_T0_A0(ot + s->mem_index);
4320
        } else {
4321
            gen_op_mov_TN_reg(ot, 0, rm);
4322
        }
4323

    
4324
        switch(op) {
4325
        case 0: /* test */
4326
            val = insn_get(s, ot);
4327
            gen_op_movl_T1_im(val);
4328
            gen_op_testl_T0_T1_cc();
4329
            s->cc_op = CC_OP_LOGICB + ot;
4330
            break;
4331
        case 2: /* not */
4332
            tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
4333
            if (mod != 3) {
4334
                gen_op_st_T0_A0(ot + s->mem_index);
4335
            } else {
4336
                gen_op_mov_reg_T0(ot, rm);
4337
            }
4338
            break;
4339
        case 3: /* neg */
4340
            tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
4341
            if (mod != 3) {
4342
                gen_op_st_T0_A0(ot + s->mem_index);
4343
            } else {
4344
                gen_op_mov_reg_T0(ot, rm);
4345
            }
4346
            gen_op_update_neg_cc();
4347
            s->cc_op = CC_OP_SUBB + ot;
4348
            break;
4349
        case 4: /* mul */
4350
            switch(ot) {
4351
            case OT_BYTE:
4352
                gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX);
4353
                tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
4354
                tcg_gen_ext8u_tl(cpu_T[1], cpu_T[1]);
4355
                /* XXX: use 32 bit mul which could be faster */
4356
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4357
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
4358
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4359
                tcg_gen_andi_tl(cpu_cc_src, cpu_T[0], 0xff00);
4360
                s->cc_op = CC_OP_MULB;
4361
                break;
4362
            case OT_WORD:
4363
                gen_op_mov_TN_reg(OT_WORD, 1, R_EAX);
4364
                tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
4365
                tcg_gen_ext16u_tl(cpu_T[1], cpu_T[1]);
4366
                /* XXX: use 32 bit mul which could be faster */
4367
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4368
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
4369
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4370
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
4371
                gen_op_mov_reg_T0(OT_WORD, R_EDX);
4372
                tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4373
                s->cc_op = CC_OP_MULW;
4374
                break;
4375
            default:
4376
            case OT_LONG:
4377
#ifdef TARGET_X86_64
4378
                gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4379
                tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
4380
                tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
4381
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4382
                gen_op_mov_reg_T0(OT_LONG, R_EAX);
4383
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4384
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
4385
                gen_op_mov_reg_T0(OT_LONG, R_EDX);
4386
                tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4387
#else
4388
                {
4389
                    TCGv_i64 t0, t1;
4390
                    t0 = tcg_temp_new_i64();
4391
                    t1 = tcg_temp_new_i64();
4392
                    gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4393
                    tcg_gen_extu_i32_i64(t0, cpu_T[0]);
4394
                    tcg_gen_extu_i32_i64(t1, cpu_T[1]);
4395
                    tcg_gen_mul_i64(t0, t0, t1);
4396
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4397
                    gen_op_mov_reg_T0(OT_LONG, R_EAX);
4398
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4399
                    tcg_gen_shri_i64(t0, t0, 32);
4400
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4401
                    gen_op_mov_reg_T0(OT_LONG, R_EDX);
4402
                    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4403
                }
4404
#endif
4405
                s->cc_op = CC_OP_MULL;
4406
                break;
4407
#ifdef TARGET_X86_64
4408
            case OT_QUAD:
4409
                gen_helper_mulq_EAX_T0(cpu_T[0]);
4410
                s->cc_op = CC_OP_MULQ;
4411
                break;
4412
#endif
4413
            }
4414
            break;
4415
        case 5: /* imul */
4416
            switch(ot) {
4417
            case OT_BYTE:
4418
                gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX);
4419
                tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
4420
                tcg_gen_ext8s_tl(cpu_T[1], cpu_T[1]);
4421
                /* XXX: use 32 bit mul which could be faster */
4422
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4423
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
4424
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4425
                tcg_gen_ext8s_tl(cpu_tmp0, cpu_T[0]);
4426
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4427
                s->cc_op = CC_OP_MULB;
4428
                break;
4429
            case OT_WORD:
4430
                gen_op_mov_TN_reg(OT_WORD, 1, R_EAX);
4431
                tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4432
                tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
4433
                /* XXX: use 32 bit mul which could be faster */
4434
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4435
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
4436
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4437
                tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
4438
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4439
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
4440
                gen_op_mov_reg_T0(OT_WORD, R_EDX);
4441
                s->cc_op = CC_OP_MULW;
4442
                break;
4443
            default:
4444
            case OT_LONG:
4445
#ifdef TARGET_X86_64
4446
                gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4447
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4448
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
4449
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4450
                gen_op_mov_reg_T0(OT_LONG, R_EAX);
4451
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4452
                tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
4453
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4454
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
4455
                gen_op_mov_reg_T0(OT_LONG, R_EDX);
4456
#else
4457
                {
4458
                    TCGv_i64 t0, t1;
4459
                    t0 = tcg_temp_new_i64();
4460
                    t1 = tcg_temp_new_i64();
4461
                    gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4462
                    tcg_gen_ext_i32_i64(t0, cpu_T[0]);
4463
                    tcg_gen_ext_i32_i64(t1, cpu_T[1]);
4464
                    tcg_gen_mul_i64(t0, t0, t1);
4465
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4466
                    gen_op_mov_reg_T0(OT_LONG, R_EAX);
4467
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4468
                    tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
4469
                    tcg_gen_shri_i64(t0, t0, 32);
4470
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4471
                    gen_op_mov_reg_T0(OT_LONG, R_EDX);
4472
                    tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4473
                }
4474
#endif
4475
                s->cc_op = CC_OP_MULL;
4476
                break;
4477
#ifdef TARGET_X86_64
4478
            case OT_QUAD:
4479
                gen_helper_imulq_EAX_T0(cpu_T[0]);
4480
                s->cc_op = CC_OP_MULQ;
4481
                break;
4482
#endif
4483
            }
4484
            break;
4485
        case 6: /* div */
4486
            switch(ot) {
4487
            case OT_BYTE:
4488
                gen_jmp_im(pc_start - s->cs_base);
4489
                gen_helper_divb_AL(cpu_T[0]);
4490
                break;
4491
            case OT_WORD:
4492
                gen_jmp_im(pc_start - s->cs_base);
4493
                gen_helper_divw_AX(cpu_T[0]);
4494
                break;
4495
            default:
4496
            case OT_LONG:
4497
                gen_jmp_im(pc_start - s->cs_base);
4498
                gen_helper_divl_EAX(cpu_T[0]);
4499
                break;
4500
#ifdef TARGET_X86_64
4501
            case OT_QUAD:
4502
                gen_jmp_im(pc_start - s->cs_base);
4503
                gen_helper_divq_EAX(cpu_T[0]);
4504
                break;
4505
#endif
4506
            }
4507
            break;
4508
        case 7: /* idiv */
4509
            switch(ot) {
4510
            case OT_BYTE:
4511
                gen_jmp_im(pc_start - s->cs_base);
4512
                gen_helper_idivb_AL(cpu_T[0]);
4513
                break;
4514
            case OT_WORD:
4515
                gen_jmp_im(pc_start - s->cs_base);
4516
                gen_helper_idivw_AX(cpu_T[0]);
4517
                break;
4518
            default:
4519
            case OT_LONG:
4520
                gen_jmp_im(pc_start - s->cs_base);
4521
                gen_helper_idivl_EAX(cpu_T[0]);
4522
                break;
4523
#ifdef TARGET_X86_64
4524
            case OT_QUAD:
4525
                gen_jmp_im(pc_start - s->cs_base);
4526
                gen_helper_idivq_EAX(cpu_T[0]);
4527
                break;
4528
#endif
4529
            }
4530
            break;
4531
        default:
4532
            goto illegal_op;
4533
        }
4534
        break;
4535

    
4536
    case 0xfe: /* GRP4 */
4537
    case 0xff: /* GRP5 */
4538
        if ((b & 1) == 0)
4539
            ot = OT_BYTE;
4540
        else
4541
            ot = dflag + OT_WORD;
4542

    
4543
        modrm = ldub_code(s->pc++);
4544
        mod = (modrm >> 6) & 3;
4545
        rm = (modrm & 7) | REX_B(s);
4546
        op = (modrm >> 3) & 7;
4547
        if (op >= 2 && b == 0xfe) {
4548
            goto illegal_op;
4549
        }
4550
        if (CODE64(s)) {
4551
            if (op == 2 || op == 4) {
4552
                /* operand size for jumps is 64 bit */
4553
                ot = OT_QUAD;
4554
            } else if (op == 3 || op == 5) {
4555
                /* for call calls, the operand is 16 or 32 bit, even
4556
                   in long mode */
4557
                ot = dflag ? OT_LONG : OT_WORD;
4558
            } else if (op == 6) {
4559
                /* default push size is 64 bit */
4560
                ot = dflag ? OT_QUAD : OT_WORD;
4561
            }
4562
        }
4563
        if (mod != 3) {
4564
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4565
            if (op >= 2 && op != 3 && op != 5)
4566
                gen_op_ld_T0_A0(ot + s->mem_index);
4567
        } else {
4568
            gen_op_mov_TN_reg(ot, 0, rm);
4569
        }
4570

    
4571
        switch(op) {
4572
        case 0: /* inc Ev */
4573
            if (mod != 3)
4574
                opreg = OR_TMP0;
4575
            else
4576
                opreg = rm;
4577
            gen_inc(s, ot, opreg, 1);
4578
            break;
4579
        case 1: /* dec Ev */
4580
            if (mod != 3)
4581
                opreg = OR_TMP0;
4582
            else
4583
                opreg = rm;
4584
            gen_inc(s, ot, opreg, -1);
4585
            break;
4586
        case 2: /* call Ev */
4587
            /* XXX: optimize if memory (no 'and' is necessary) */
4588
            if (s->dflag == 0)
4589
                gen_op_andl_T0_ffff();
4590
            next_eip = s->pc - s->cs_base;
4591
            gen_movtl_T1_im(next_eip);
4592
            gen_push_T1(s);
4593
            gen_op_jmp_T0();
4594
            gen_eob(s);
4595
            break;
4596
        case 3: /* lcall Ev */
4597
            gen_op_ld_T1_A0(ot + s->mem_index);
4598
            gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4599
            gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
4600
        do_lcall:
4601
            if (s->pe && !s->vm86) {
4602
                if (s->cc_op != CC_OP_DYNAMIC)
4603
                    gen_op_set_cc_op(s->cc_op);
4604
                gen_jmp_im(pc_start - s->cs_base);
4605
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4606
                gen_helper_lcall_protected(cpu_tmp2_i32, cpu_T[1],
4607
                                           tcg_const_i32(dflag), 
4608
                                           tcg_const_i32(s->pc - pc_start));
4609
            } else {
4610
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4611
                gen_helper_lcall_real(cpu_tmp2_i32, cpu_T[1],
4612
                                      tcg_const_i32(dflag), 
4613
                                      tcg_const_i32(s->pc - s->cs_base));
4614
            }
4615
            gen_eob(s);
4616
            break;
4617
        case 4: /* jmp Ev */
4618
            if (s->dflag == 0)
4619
                gen_op_andl_T0_ffff();
4620
            gen_op_jmp_T0();
4621
            gen_eob(s);
4622
            break;
4623
        case 5: /* ljmp Ev */
4624
            gen_op_ld_T1_A0(ot + s->mem_index);
4625
            gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4626
            gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
4627
        do_ljmp:
4628
            if (s->pe && !s->vm86) {
4629
                if (s->cc_op != CC_OP_DYNAMIC)
4630
                    gen_op_set_cc_op(s->cc_op);
4631
                gen_jmp_im(pc_start - s->cs_base);
4632
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4633
                gen_helper_ljmp_protected(cpu_tmp2_i32, cpu_T[1],
4634
                                          tcg_const_i32(s->pc - pc_start));
4635
            } else {
4636
                gen_op_movl_seg_T0_vm(R_CS);
4637
                gen_op_movl_T0_T1();
4638
                gen_op_jmp_T0();
4639
            }
4640
            gen_eob(s);
4641
            break;
4642
        case 6: /* push Ev */
4643
            gen_push_T0(s);
4644
            break;
4645
        default:
4646
            goto illegal_op;
4647
        }
4648
        break;
4649

    
4650
    case 0x84: /* test Ev, Gv */
4651
    case 0x85:
4652
        if ((b & 1) == 0)
4653
            ot = OT_BYTE;
4654
        else
4655
            ot = dflag + OT_WORD;
4656

    
4657
        modrm = ldub_code(s->pc++);
4658
        mod = (modrm >> 6) & 3;
4659
        rm = (modrm & 7) | REX_B(s);
4660
        reg = ((modrm >> 3) & 7) | rex_r;
4661

    
4662
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
4663
        gen_op_mov_TN_reg(ot, 1, reg);
4664
        gen_op_testl_T0_T1_cc();
4665
        s->cc_op = CC_OP_LOGICB + ot;
4666
        break;
4667

    
4668
    case 0xa8: /* test eAX, Iv */
4669
    case 0xa9:
4670
        if ((b & 1) == 0)
4671
            ot = OT_BYTE;
4672
        else
4673
            ot = dflag + OT_WORD;
4674
        val = insn_get(s, ot);
4675

    
4676
        gen_op_mov_TN_reg(ot, 0, OR_EAX);
4677
        gen_op_movl_T1_im(val);
4678
        gen_op_testl_T0_T1_cc();
4679
        s->cc_op = CC_OP_LOGICB + ot;
4680
        break;
4681

    
4682
    case 0x98: /* CWDE/CBW */
4683
#ifdef TARGET_X86_64
4684
        if (dflag == 2) {
4685
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
4686
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4687
            gen_op_mov_reg_T0(OT_QUAD, R_EAX);
4688
        } else
4689
#endif
4690
        if (dflag == 1) {
4691
            gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
4692
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4693
            gen_op_mov_reg_T0(OT_LONG, R_EAX);
4694
        } else {
4695
            gen_op_mov_TN_reg(OT_BYTE, 0, R_EAX);
4696
            tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
4697
            gen_op_mov_reg_T0(OT_WORD, R_EAX);
4698
        }
4699
        break;
4700
    case 0x99: /* CDQ/CWD */
4701
#ifdef TARGET_X86_64
4702
        if (dflag == 2) {
4703
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
4704
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 63);
4705
            gen_op_mov_reg_T0(OT_QUAD, R_EDX);
4706
        } else
4707
#endif
4708
        if (dflag == 1) {
4709
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
4710
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4711
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 31);
4712
            gen_op_mov_reg_T0(OT_LONG, R_EDX);
4713
        } else {
4714
            gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
4715
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4716
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 15);
4717
            gen_op_mov_reg_T0(OT_WORD, R_EDX);
4718
        }
4719
        break;
4720
    case 0x1af: /* imul Gv, Ev */
4721
    case 0x69: /* imul Gv, Ev, I */
4722
    case 0x6b:
4723
        ot = dflag + OT_WORD;
4724
        modrm = ldub_code(s->pc++);
4725
        reg = ((modrm >> 3) & 7) | rex_r;
4726
        if (b == 0x69)
4727
            s->rip_offset = insn_const_size(ot);
4728
        else if (b == 0x6b)
4729
            s->rip_offset = 1;
4730
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
4731
        if (b == 0x69) {
4732
            val = insn_get(s, ot);
4733
            gen_op_movl_T1_im(val);
4734
        } else if (b == 0x6b) {
4735
            val = (int8_t)insn_get(s, OT_BYTE);
4736
            gen_op_movl_T1_im(val);
4737
        } else {
4738
            gen_op_mov_TN_reg(ot, 1, reg);
4739
        }
4740

    
4741
#ifdef TARGET_X86_64
4742
        if (ot == OT_QUAD) {
4743
            gen_helper_imulq_T0_T1(cpu_T[0], cpu_T[0], cpu_T[1]);
4744
        } else
4745
#endif
4746
        if (ot == OT_LONG) {
4747
#ifdef TARGET_X86_64
4748
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4749
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
4750
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4751
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4752
                tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
4753
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4754
#else
4755
                {
4756
                    TCGv_i64 t0, t1;
4757
                    t0 = tcg_temp_new_i64();
4758
                    t1 = tcg_temp_new_i64();
4759
                    tcg_gen_ext_i32_i64(t0, cpu_T[0]);
4760
                    tcg_gen_ext_i32_i64(t1, cpu_T[1]);
4761
                    tcg_gen_mul_i64(t0, t0, t1);
4762
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4763
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4764
                    tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
4765
                    tcg_gen_shri_i64(t0, t0, 32);
4766
                    tcg_gen_trunc_i64_i32(cpu_T[1], t0);
4767
                    tcg_gen_sub_tl(cpu_cc_src, cpu_T[1], cpu_tmp0);
4768
                }
4769
#endif
4770
        } else {
4771
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4772
            tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
4773
            /* XXX: use 32 bit mul which could be faster */
4774
            tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4775
            tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4776
            tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
4777
            tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4778
        }
4779
        gen_op_mov_reg_T0(ot, reg);
4780
        s->cc_op = CC_OP_MULB + ot;
4781
        break;
4782
    case 0x1c0:
4783
    case 0x1c1: /* xadd Ev, Gv */
4784
        if ((b & 1) == 0)
4785
            ot = OT_BYTE;
4786
        else
4787
            ot = dflag + OT_WORD;
4788
        modrm = ldub_code(s->pc++);
4789
        reg = ((modrm >> 3) & 7) | rex_r;
4790
        mod = (modrm >> 6) & 3;
4791
        if (mod == 3) {
4792
            rm = (modrm & 7) | REX_B(s);
4793
            gen_op_mov_TN_reg(ot, 0, reg);
4794
            gen_op_mov_TN_reg(ot, 1, rm);
4795
            gen_op_addl_T0_T1();
4796
            gen_op_mov_reg_T1(ot, reg);
4797
            gen_op_mov_reg_T0(ot, rm);
4798
        } else {
4799
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4800
            gen_op_mov_TN_reg(ot, 0, reg);
4801
            gen_op_ld_T1_A0(ot + s->mem_index);
4802
            gen_op_addl_T0_T1();
4803
            gen_op_st_T0_A0(ot + s->mem_index);
4804
            gen_op_mov_reg_T1(ot, reg);
4805
        }
4806
        gen_op_update2_cc();
4807
        s->cc_op = CC_OP_ADDB + ot;
4808
        break;
4809
    case 0x1b0:
4810
    case 0x1b1: /* cmpxchg Ev, Gv */
4811
        {
4812
            int label1, label2;
4813
            TCGv t0, t1, t2, a0;
4814

    
4815
            if ((b & 1) == 0)
4816
                ot = OT_BYTE;
4817
            else
4818
                ot = dflag + OT_WORD;
4819
            modrm = ldub_code(s->pc++);
4820
            reg = ((modrm >> 3) & 7) | rex_r;
4821
            mod = (modrm >> 6) & 3;
4822
            t0 = tcg_temp_local_new();
4823
            t1 = tcg_temp_local_new();
4824
            t2 = tcg_temp_local_new();
4825
            a0 = tcg_temp_local_new();
4826
            gen_op_mov_v_reg(ot, t1, reg);
4827
            if (mod == 3) {
4828
                rm = (modrm & 7) | REX_B(s);
4829
                gen_op_mov_v_reg(ot, t0, rm);
4830
            } else {
4831
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4832
                tcg_gen_mov_tl(a0, cpu_A0);
4833
                gen_op_ld_v(ot + s->mem_index, t0, a0);
4834
                rm = 0; /* avoid warning */
4835
            }
4836
            label1 = gen_new_label();
4837
            tcg_gen_ld_tl(t2, cpu_env, offsetof(CPUState, regs[R_EAX]));
4838
            tcg_gen_sub_tl(t2, t2, t0);
4839
            gen_extu(ot, t2);
4840
            tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
4841
            if (mod == 3) {
4842
                label2 = gen_new_label();
4843
                gen_op_mov_reg_v(ot, R_EAX, t0);
4844
                tcg_gen_br(label2);
4845
                gen_set_label(label1);
4846
                gen_op_mov_reg_v(ot, rm, t1);
4847
                gen_set_label(label2);
4848
            } else {
4849
                tcg_gen_mov_tl(t1, t0);
4850
                gen_op_mov_reg_v(ot, R_EAX, t0);
4851
                gen_set_label(label1);
4852
                /* always store */
4853
                gen_op_st_v(ot + s->mem_index, t1, a0);
4854
            }
4855
            tcg_gen_mov_tl(cpu_cc_src, t0);
4856
            tcg_gen_mov_tl(cpu_cc_dst, t2);
4857
            s->cc_op = CC_OP_SUBB + ot;
4858
            tcg_temp_free(t0);
4859
            tcg_temp_free(t1);
4860
            tcg_temp_free(t2);
4861
            tcg_temp_free(a0);
4862
        }
4863
        break;
4864
    case 0x1c7: /* cmpxchg8b */
4865
        modrm = ldub_code(s->pc++);
4866
        mod = (modrm >> 6) & 3;
4867
        if ((mod == 3) || ((modrm & 0x38) != 0x8))
4868
            goto illegal_op;
4869
#ifdef TARGET_X86_64
4870
        if (dflag == 2) {
4871
            if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
4872
                goto illegal_op;
4873
            gen_jmp_im(pc_start - s->cs_base);
4874
            if (s->cc_op != CC_OP_DYNAMIC)
4875
                gen_op_set_cc_op(s->cc_op);
4876
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4877
            gen_helper_cmpxchg16b(cpu_A0);
4878
        } else
4879
#endif        
4880
        {
4881
            if (!(s->cpuid_features & CPUID_CX8))
4882
                goto illegal_op;
4883
            gen_jmp_im(pc_start - s->cs_base);
4884
            if (s->cc_op != CC_OP_DYNAMIC)
4885
                gen_op_set_cc_op(s->cc_op);
4886
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4887
            gen_helper_cmpxchg8b(cpu_A0);
4888
        }
4889
        s->cc_op = CC_OP_EFLAGS;
4890
        break;
4891

    
4892
        /**************************/
4893
        /* push/pop */
4894
    case 0x50 ... 0x57: /* push */
4895
        gen_op_mov_TN_reg(OT_LONG, 0, (b & 7) | REX_B(s));
4896
        gen_push_T0(s);
4897
        break;
4898
    case 0x58 ... 0x5f: /* pop */
4899
        if (CODE64(s)) {
4900
            ot = dflag ? OT_QUAD : OT_WORD;
4901
        } else {
4902
            ot = dflag + OT_WORD;
4903
        }
4904
        gen_pop_T0(s);
4905
        /* NOTE: order is important for pop %sp */
4906
        gen_pop_update(s);
4907
        gen_op_mov_reg_T0(ot, (b & 7) | REX_B(s));
4908
        break;
4909
    case 0x60: /* pusha */
4910
        if (CODE64(s))
4911
            goto illegal_op;
4912
        gen_pusha(s);
4913
        break;
4914
    case 0x61: /* popa */
4915
        if (CODE64(s))
4916
            goto illegal_op;
4917
        gen_popa(s);
4918
        break;
4919
    case 0x68: /* push Iv */
4920
    case 0x6a:
4921
        if (CODE64(s)) {
4922
            ot = dflag ? OT_QUAD : OT_WORD;
4923
        } else {
4924
            ot = dflag + OT_WORD;
4925
        }
4926
        if (b == 0x68)
4927
            val = insn_get(s, ot);
4928
        else
4929
            val = (int8_t)insn_get(s, OT_BYTE);
4930
        gen_op_movl_T0_im(val);
4931
        gen_push_T0(s);
4932
        break;
4933
    case 0x8f: /* pop Ev */
4934
        if (CODE64(s)) {
4935
            ot = dflag ? OT_QUAD : OT_WORD;
4936
        } else {
4937
            ot = dflag + OT_WORD;
4938
        }
4939
        modrm = ldub_code(s->pc++);
4940
        mod = (modrm >> 6) & 3;
4941
        gen_pop_T0(s);
4942
        if (mod == 3) {
4943
            /* NOTE: order is important for pop %sp */
4944
            gen_pop_update(s);
4945
            rm = (modrm & 7) | REX_B(s);
4946
            gen_op_mov_reg_T0(ot, rm);
4947
        } else {
4948
            /* NOTE: order is important too for MMU exceptions */
4949
            s->popl_esp_hack = 1 << ot;
4950
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
4951
            s->popl_esp_hack = 0;
4952
            gen_pop_update(s);
4953
        }
4954
        break;
4955
    case 0xc8: /* enter */
4956
        {
4957
            int level;
4958
            val = lduw_code(s->pc);
4959
            s->pc += 2;
4960
            level = ldub_code(s->pc++);
4961
            gen_enter(s, val, level);
4962
        }
4963
        break;
4964
    case 0xc9: /* leave */
4965
        /* XXX: exception not precise (ESP is updated before potential exception) */
4966
        if (CODE64(s)) {
4967
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EBP);
4968
            gen_op_mov_reg_T0(OT_QUAD, R_ESP);
4969
        } else if (s->ss32) {
4970
            gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
4971
            gen_op_mov_reg_T0(OT_LONG, R_ESP);
4972
        } else {
4973
            gen_op_mov_TN_reg(OT_WORD, 0, R_EBP);
4974
            gen_op_mov_reg_T0(OT_WORD, R_ESP);
4975
        }
4976
        gen_pop_T0(s);
4977
        if (CODE64(s)) {
4978
            ot = dflag ? OT_QUAD : OT_WORD;
4979
        } else {
4980
            ot = dflag + OT_WORD;
4981
        }
4982
        gen_op_mov_reg_T0(ot, R_EBP);
4983
        gen_pop_update(s);
4984
        break;
4985
    case 0x06: /* push es */
4986
    case 0x0e: /* push cs */
4987
    case 0x16: /* push ss */
4988
    case 0x1e: /* push ds */
4989
        if (CODE64(s))
4990
            goto illegal_op;
4991
        gen_op_movl_T0_seg(b >> 3);
4992
        gen_push_T0(s);
4993
        break;
4994
    case 0x1a0: /* push fs */
4995
    case 0x1a8: /* push gs */
4996
        gen_op_movl_T0_seg((b >> 3) & 7);
4997
        gen_push_T0(s);
4998
        break;
4999
    case 0x07: /* pop es */
5000
    case 0x17: /* pop ss */
5001
    case 0x1f: /* pop ds */
5002
        if (CODE64(s))
5003
            goto illegal_op;
5004
        reg = b >> 3;
5005
        gen_pop_T0(s);
5006
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
5007
        gen_pop_update(s);
5008
        if (reg == R_SS) {
5009
            /* if reg == SS, inhibit interrupts/trace. */
5010
            /* If several instructions disable interrupts, only the
5011
               _first_ does it */
5012
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
5013
                gen_helper_set_inhibit_irq();
5014
            s->tf = 0;
5015
        }
5016
        if (s->is_jmp) {
5017
            gen_jmp_im(s->pc - s->cs_base);
5018
            gen_eob(s);
5019
        }
5020
        break;
5021
    case 0x1a1: /* pop fs */
5022
    case 0x1a9: /* pop gs */
5023
        gen_pop_T0(s);
5024
        gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
5025
        gen_pop_update(s);
5026
        if (s->is_jmp) {
5027
            gen_jmp_im(s->pc - s->cs_base);
5028
            gen_eob(s);
5029
        }
5030
        break;
5031

    
5032
        /**************************/
5033
        /* mov */
5034
    case 0x88:
5035
    case 0x89: /* mov Gv, Ev */
5036
        if ((b & 1) == 0)
5037
            ot = OT_BYTE;
5038
        else
5039
            ot = dflag + OT_WORD;
5040
        modrm = ldub_code(s->pc++);
5041
        reg = ((modrm >> 3) & 7) | rex_r;
5042

    
5043
        /* generate a generic store */
5044
        gen_ldst_modrm(s, modrm, ot, reg, 1);
5045
        break;
5046
    case 0xc6:
5047
    case 0xc7: /* mov Ev, Iv */
5048
        if ((b & 1) == 0)
5049
            ot = OT_BYTE;
5050
        else
5051
            ot = dflag + OT_WORD;
5052
        modrm = ldub_code(s->pc++);
5053
        mod = (modrm >> 6) & 3;
5054
        if (mod != 3) {
5055
            s->rip_offset = insn_const_size(ot);
5056
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5057
        }
5058
        val = insn_get(s, ot);
5059
        gen_op_movl_T0_im(val);
5060
        if (mod != 3)
5061
            gen_op_st_T0_A0(ot + s->mem_index);
5062
        else
5063
            gen_op_mov_reg_T0(ot, (modrm & 7) | REX_B(s));
5064
        break;
5065
    case 0x8a:
5066
    case 0x8b: /* mov Ev, Gv */
5067
        if ((b & 1) == 0)
5068
            ot = OT_BYTE;
5069
        else
5070
            ot = OT_WORD + dflag;
5071
        modrm = ldub_code(s->pc++);
5072
        reg = ((modrm >> 3) & 7) | rex_r;
5073

    
5074
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
5075
        gen_op_mov_reg_T0(ot, reg);
5076
        break;
5077
    case 0x8e: /* mov seg, Gv */
5078
        modrm = ldub_code(s->pc++);
5079
        reg = (modrm >> 3) & 7;
5080
        if (reg >= 6 || reg == R_CS)
5081
            goto illegal_op;
5082
        gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
5083
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
5084
        if (reg == R_SS) {
5085
            /* if reg == SS, inhibit interrupts/trace */
5086
            /* If several instructions disable interrupts, only the
5087
               _first_ does it */
5088
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
5089
                gen_helper_set_inhibit_irq();
5090
            s->tf = 0;
5091
        }
5092
        if (s->is_jmp) {
5093
            gen_jmp_im(s->pc - s->cs_base);
5094
            gen_eob(s);
5095
        }
5096
        break;
5097
    case 0x8c: /* mov Gv, seg */
5098
        modrm = ldub_code(s->pc++);
5099
        reg = (modrm >> 3) & 7;
5100
        mod = (modrm >> 6) & 3;
5101
        if (reg >= 6)
5102
            goto illegal_op;
5103
        gen_op_movl_T0_seg(reg);
5104
        if (mod == 3)
5105
            ot = OT_WORD + dflag;
5106
        else
5107
            ot = OT_WORD;
5108
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
5109
        break;
5110

    
5111
    case 0x1b6: /* movzbS Gv, Eb */
5112
    case 0x1b7: /* movzwS Gv, Eb */
5113
    case 0x1be: /* movsbS Gv, Eb */
5114
    case 0x1bf: /* movswS Gv, Eb */
5115
        {
5116
            int d_ot;
5117
            /* d_ot is the size of destination */
5118
            d_ot = dflag + OT_WORD;
5119
            /* ot is the size of source */
5120
            ot = (b & 1) + OT_BYTE;
5121
            modrm = ldub_code(s->pc++);
5122
            reg = ((modrm >> 3) & 7) | rex_r;
5123
            mod = (modrm >> 6) & 3;
5124
            rm = (modrm & 7) | REX_B(s);
5125

    
5126
            if (mod == 3) {
5127
                gen_op_mov_TN_reg(ot, 0, rm);
5128
                switch(ot | (b & 8)) {
5129
                case OT_BYTE:
5130
                    tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
5131
                    break;
5132
                case OT_BYTE | 8:
5133
                    tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
5134
                    break;
5135
                case OT_WORD:
5136
                    tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
5137
                    break;
5138
                default:
5139
                case OT_WORD | 8:
5140
                    tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
5141
                    break;
5142
                }
5143
                gen_op_mov_reg_T0(d_ot, reg);
5144
            } else {
5145
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5146
                if (b & 8) {
5147
                    gen_op_lds_T0_A0(ot + s->mem_index);
5148
                } else {
5149
                    gen_op_ldu_T0_A0(ot + s->mem_index);
5150
                }
5151
                gen_op_mov_reg_T0(d_ot, reg);
5152
            }
5153
        }
5154
        break;
5155

    
5156
    case 0x8d: /* lea */
5157
        ot = dflag + OT_WORD;
5158
        modrm = ldub_code(s->pc++);
5159
        mod = (modrm >> 6) & 3;
5160
        if (mod == 3)
5161
            goto illegal_op;
5162
        reg = ((modrm >> 3) & 7) | rex_r;
5163
        /* we must ensure that no segment is added */
5164
        s->override = -1;
5165
        val = s->addseg;
5166
        s->addseg = 0;
5167
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5168
        s->addseg = val;
5169
        gen_op_mov_reg_A0(ot - OT_WORD, reg);
5170
        break;
5171

    
5172
    case 0xa0: /* mov EAX, Ov */
5173
    case 0xa1:
5174
    case 0xa2: /* mov Ov, EAX */
5175
    case 0xa3:
5176
        {
5177
            target_ulong offset_addr;
5178

    
5179
            if ((b & 1) == 0)
5180
                ot = OT_BYTE;
5181
            else
5182
                ot = dflag + OT_WORD;
5183
#ifdef TARGET_X86_64
5184
            if (s->aflag == 2) {
5185
                offset_addr = ldq_code(s->pc);
5186
                s->pc += 8;
5187
                gen_op_movq_A0_im(offset_addr);
5188
            } else
5189
#endif
5190
            {
5191
                if (s->aflag) {
5192
                    offset_addr = insn_get(s, OT_LONG);
5193
                } else {
5194
                    offset_addr = insn_get(s, OT_WORD);
5195
                }
5196
                gen_op_movl_A0_im(offset_addr);
5197
            }
5198
            gen_add_A0_ds_seg(s);
5199
            if ((b & 2) == 0) {
5200
                gen_op_ld_T0_A0(ot + s->mem_index);
5201
                gen_op_mov_reg_T0(ot, R_EAX);
5202
            } else {
5203
                gen_op_mov_TN_reg(ot, 0, R_EAX);
5204
                gen_op_st_T0_A0(ot + s->mem_index);
5205
            }
5206
        }
5207
        break;
5208
    case 0xd7: /* xlat */
5209
#ifdef TARGET_X86_64
5210
        if (s->aflag == 2) {
5211
            gen_op_movq_A0_reg(R_EBX);
5212
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
5213
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
5214
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
5215
        } else
5216
#endif
5217
        {
5218
            gen_op_movl_A0_reg(R_EBX);
5219
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
5220
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
5221
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
5222
            if (s->aflag == 0)
5223
                gen_op_andl_A0_ffff();
5224
            else
5225
                tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
5226
        }
5227
        gen_add_A0_ds_seg(s);
5228
        gen_op_ldu_T0_A0(OT_BYTE + s->mem_index);
5229
        gen_op_mov_reg_T0(OT_BYTE, R_EAX);
5230
        break;
5231
    case 0xb0 ... 0xb7: /* mov R, Ib */
5232
        val = insn_get(s, OT_BYTE);
5233
        gen_op_movl_T0_im(val);
5234
        gen_op_mov_reg_T0(OT_BYTE, (b & 7) | REX_B(s));
5235
        break;
5236
    case 0xb8 ... 0xbf: /* mov R, Iv */
5237
#ifdef TARGET_X86_64
5238
        if (dflag == 2) {
5239
            uint64_t tmp;
5240
            /* 64 bit case */
5241
            tmp = ldq_code(s->pc);
5242
            s->pc += 8;
5243
            reg = (b & 7) | REX_B(s);
5244
            gen_movtl_T0_im(tmp);
5245
            gen_op_mov_reg_T0(OT_QUAD, reg);
5246
        } else
5247
#endif
5248
        {
5249
            ot = dflag ? OT_LONG : OT_WORD;
5250
            val = insn_get(s, ot);
5251
            reg = (b & 7) | REX_B(s);
5252
            gen_op_movl_T0_im(val);
5253
            gen_op_mov_reg_T0(ot, reg);
5254
        }
5255
        break;
5256

    
5257
    case 0x91 ... 0x97: /* xchg R, EAX */
5258
        ot = dflag + OT_WORD;
5259
        reg = (b & 7) | REX_B(s);
5260
        rm = R_EAX;
5261
        goto do_xchg_reg;
5262
    case 0x86:
5263
    case 0x87: /* xchg Ev, Gv */
5264
        if ((b & 1) == 0)
5265
            ot = OT_BYTE;
5266
        else
5267
            ot = dflag + OT_WORD;
5268
        modrm = ldub_code(s->pc++);
5269
        reg = ((modrm >> 3) & 7) | rex_r;
5270
        mod = (modrm >> 6) & 3;
5271
        if (mod == 3) {
5272
            rm = (modrm & 7) | REX_B(s);
5273
        do_xchg_reg:
5274
            gen_op_mov_TN_reg(ot, 0, reg);
5275
            gen_op_mov_TN_reg(ot, 1, rm);
5276
            gen_op_mov_reg_T0(ot, rm);
5277
            gen_op_mov_reg_T1(ot, reg);
5278
        } else {
5279
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5280
            gen_op_mov_TN_reg(ot, 0, reg);
5281
            /* for xchg, lock is implicit */
5282
            if (!(prefixes & PREFIX_LOCK))
5283
                gen_helper_lock();
5284
            gen_op_ld_T1_A0(ot + s->mem_index);
5285
            gen_op_st_T0_A0(ot + s->mem_index);
5286
            if (!(prefixes & PREFIX_LOCK))
5287
                gen_helper_unlock();
5288
            gen_op_mov_reg_T1(ot, reg);
5289
        }
5290
        break;
5291
    case 0xc4: /* les Gv */
5292
        if (CODE64(s))
5293
            goto illegal_op;
5294
        op = R_ES;
5295
        goto do_lxx;
5296
    case 0xc5: /* lds Gv */
5297
        if (CODE64(s))
5298
            goto illegal_op;
5299
        op = R_DS;
5300
        goto do_lxx;
5301
    case 0x1b2: /* lss Gv */
5302
        op = R_SS;
5303
        goto do_lxx;
5304
    case 0x1b4: /* lfs Gv */
5305
        op = R_FS;
5306
        goto do_lxx;
5307
    case 0x1b5: /* lgs Gv */
5308
        op = R_GS;
5309
    do_lxx:
5310
        ot = dflag ? OT_LONG : OT_WORD;
5311
        modrm = ldub_code(s->pc++);
5312
        reg = ((modrm >> 3) & 7) | rex_r;
5313
        mod = (modrm >> 6) & 3;
5314
        if (mod == 3)
5315
            goto illegal_op;
5316
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5317
        gen_op_ld_T1_A0(ot + s->mem_index);
5318
        gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
5319
        /* load the segment first to handle exceptions properly */
5320
        gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
5321
        gen_movl_seg_T0(s, op, pc_start - s->cs_base);
5322
        /* then put the data */
5323
        gen_op_mov_reg_T1(ot, reg);
5324
        if (s->is_jmp) {
5325
            gen_jmp_im(s->pc - s->cs_base);
5326
            gen_eob(s);
5327
        }
5328
        break;
5329

    
5330
        /************************/
5331
        /* shifts */
5332
    case 0xc0:
5333
    case 0xc1:
5334
        /* shift Ev,Ib */
5335
        shift = 2;
5336
    grp2:
5337
        {
5338
            if ((b & 1) == 0)
5339
                ot = OT_BYTE;
5340
            else
5341
                ot = dflag + OT_WORD;
5342

    
5343
            modrm = ldub_code(s->pc++);
5344
            mod = (modrm >> 6) & 3;
5345
            op = (modrm >> 3) & 7;
5346

    
5347
            if (mod != 3) {
5348
                if (shift == 2) {
5349
                    s->rip_offset = 1;
5350
                }
5351
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5352
                opreg = OR_TMP0;
5353
            } else {
5354
                opreg = (modrm & 7) | REX_B(s);
5355
            }
5356

    
5357
            /* simpler op */
5358
            if (shift == 0) {
5359
                gen_shift(s, op, ot, opreg, OR_ECX);
5360
            } else {
5361
                if (shift == 2) {
5362
                    shift = ldub_code(s->pc++);
5363
                }
5364
                gen_shifti(s, op, ot, opreg, shift);
5365
            }
5366
        }
5367
        break;
5368
    case 0xd0:
5369
    case 0xd1:
5370
        /* shift Ev,1 */
5371
        shift = 1;
5372
        goto grp2;
5373
    case 0xd2:
5374
    case 0xd3:
5375
        /* shift Ev,cl */
5376
        shift = 0;
5377
        goto grp2;
5378

    
5379
    case 0x1a4: /* shld imm */
5380
        op = 0;
5381
        shift = 1;
5382
        goto do_shiftd;
5383
    case 0x1a5: /* shld cl */
5384
        op = 0;
5385
        shift = 0;
5386
        goto do_shiftd;
5387
    case 0x1ac: /* shrd imm */
5388
        op = 1;
5389
        shift = 1;
5390
        goto do_shiftd;
5391
    case 0x1ad: /* shrd cl */
5392
        op = 1;
5393
        shift = 0;
5394
    do_shiftd:
5395
        ot = dflag + OT_WORD;
5396
        modrm = ldub_code(s->pc++);
5397
        mod = (modrm >> 6) & 3;
5398
        rm = (modrm & 7) | REX_B(s);
5399
        reg = ((modrm >> 3) & 7) | rex_r;
5400
        if (mod != 3) {
5401
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5402
            opreg = OR_TMP0;
5403
        } else {
5404
            opreg = rm;
5405
        }
5406
        gen_op_mov_TN_reg(ot, 1, reg);
5407

    
5408
        if (shift) {
5409
            val = ldub_code(s->pc++);
5410
            tcg_gen_movi_tl(cpu_T3, val);
5411
        } else {
5412
            tcg_gen_ld_tl(cpu_T3, cpu_env, offsetof(CPUState, regs[R_ECX]));
5413
        }
5414
        gen_shiftd_rm_T1_T3(s, ot, opreg, op);
5415
        break;
5416

    
5417
        /************************/
5418
        /* floats */
5419
    case 0xd8 ... 0xdf:
5420
        if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
5421
            /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5422
            /* XXX: what to do if illegal op ? */
5423
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5424
            break;
5425
        }
5426
        modrm = ldub_code(s->pc++);
5427
        mod = (modrm >> 6) & 3;
5428
        rm = modrm & 7;
5429
        op = ((b & 7) << 3) | ((modrm >> 3) & 7);
5430
        if (mod != 3) {
5431
            /* memory op */
5432
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5433
            switch(op) {
5434
            case 0x00 ... 0x07: /* fxxxs */
5435
            case 0x10 ... 0x17: /* fixxxl */
5436
            case 0x20 ... 0x27: /* fxxxl */
5437
            case 0x30 ... 0x37: /* fixxx */
5438
                {
5439
                    int op1;
5440
                    op1 = op & 7;
5441

    
5442
                    switch(op >> 4) {
5443
                    case 0:
5444
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5445
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5446
                        gen_helper_flds_FT0(cpu_tmp2_i32);
5447
                        break;
5448
                    case 1:
5449
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5450
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5451
                        gen_helper_fildl_FT0(cpu_tmp2_i32);
5452
                        break;
5453
                    case 2:
5454
                        tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
5455
                                          (s->mem_index >> 2) - 1);
5456
                        gen_helper_fldl_FT0(cpu_tmp1_i64);
5457
                        break;
5458
                    case 3:
5459
                    default:
5460
                        gen_op_lds_T0_A0(OT_WORD + s->mem_index);
5461
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5462
                        gen_helper_fildl_FT0(cpu_tmp2_i32);
5463
                        break;
5464
                    }
5465

    
5466
                    gen_helper_fp_arith_ST0_FT0(op1);
5467
                    if (op1 == 3) {
5468
                        /* fcomp needs pop */
5469
                        gen_helper_fpop();
5470
                    }
5471
                }
5472
                break;
5473
            case 0x08: /* flds */
5474
            case 0x0a: /* fsts */
5475
            case 0x0b: /* fstps */
5476
            case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5477
            case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5478
            case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5479
                switch(op & 7) {
5480
                case 0:
5481
                    switch(op >> 4) {
5482
                    case 0:
5483
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5484
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5485
                        gen_helper_flds_ST0(cpu_tmp2_i32);
5486
                        break;
5487
                    case 1:
5488
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5489
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5490
                        gen_helper_fildl_ST0(cpu_tmp2_i32);
5491
                        break;
5492
                    case 2:
5493
                        tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
5494
                                          (s->mem_index >> 2) - 1);
5495
                        gen_helper_fldl_ST0(cpu_tmp1_i64);
5496
                        break;
5497
                    case 3:
5498
                    default:
5499
                        gen_op_lds_T0_A0(OT_WORD + s->mem_index);
5500
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5501
                        gen_helper_fildl_ST0(cpu_tmp2_i32);
5502
                        break;
5503
                    }
5504
                    break;
5505
                case 1:
5506
                    /* XXX: the corresponding CPUID bit must be tested ! */
5507
                    switch(op >> 4) {
5508
                    case 1:
5509
                        gen_helper_fisttl_ST0(cpu_tmp2_i32);
5510
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5511
                        gen_op_st_T0_A0(OT_LONG + s->mem_index);
5512
                        break;
5513
                    case 2:
5514
                        gen_helper_fisttll_ST0(cpu_tmp1_i64);
5515
                        tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
5516
                                          (s->mem_index >> 2) - 1);
5517
                        break;
5518
                    case 3:
5519
                    default:
5520
                        gen_helper_fistt_ST0(cpu_tmp2_i32);
5521
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5522
                        gen_op_st_T0_A0(OT_WORD + s->mem_index);
5523
                        break;
5524
                    }
5525
                    gen_helper_fpop();
5526
                    break;
5527
                default:
5528
                    switch(op >> 4) {
5529
                    case 0:
5530
                        gen_helper_fsts_ST0(cpu_tmp2_i32);
5531
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5532
                        gen_op_st_T0_A0(OT_LONG + s->mem_index);
5533
                        break;
5534
                    case 1:
5535
                        gen_helper_fistl_ST0(cpu_tmp2_i32);
5536
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5537
                        gen_op_st_T0_A0(OT_LONG + s->mem_index);
5538
                        break;
5539
                    case 2:
5540
                        gen_helper_fstl_ST0(cpu_tmp1_i64);
5541
                        tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
5542
                                          (s->mem_index >> 2) - 1);
5543
                        break;
5544
                    case 3:
5545
                    default:
5546
                        gen_helper_fist_ST0(cpu_tmp2_i32);
5547
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5548
                        gen_op_st_T0_A0(OT_WORD + s->mem_index);
5549
                        break;
5550
                    }
5551
                    if ((op & 7) == 3)
5552
                        gen_helper_fpop();
5553
                    break;
5554
                }
5555
                break;
5556
            case 0x0c: /* fldenv mem */
5557
                if (s->cc_op != CC_OP_DYNAMIC)
5558
                    gen_op_set_cc_op(s->cc_op);
5559
                gen_jmp_im(pc_start - s->cs_base);
5560
                gen_helper_fldenv(
5561
                                   cpu_A0, tcg_const_i32(s->dflag));
5562
                break;
5563
            case 0x0d: /* fldcw mem */
5564
                gen_op_ld_T0_A0(OT_WORD + s->mem_index);
5565
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5566
                gen_helper_fldcw(cpu_tmp2_i32);
5567
                break;
5568
            case 0x0e: /* fnstenv mem */
5569
                if (s->cc_op != CC_OP_DYNAMIC)
5570
                    gen_op_set_cc_op(s->cc_op);
5571
                gen_jmp_im(pc_start - s->cs_base);
5572
                gen_helper_fstenv(cpu_A0, tcg_const_i32(s->dflag));
5573
                break;
5574
            case 0x0f: /* fnstcw mem */
5575
                gen_helper_fnstcw(cpu_tmp2_i32);
5576
                tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5577
                gen_op_st_T0_A0(OT_WORD + s->mem_index);
5578
                break;
5579
            case 0x1d: /* fldt mem */
5580
                if (s->cc_op != CC_OP_DYNAMIC)
5581
                    gen_op_set_cc_op(s->cc_op);
5582
                gen_jmp_im(pc_start - s->cs_base);
5583
                gen_helper_fldt_ST0(cpu_A0);
5584
                break;
5585
            case 0x1f: /* fstpt mem */
5586
                if (s->cc_op != CC_OP_DYNAMIC)
5587
                    gen_op_set_cc_op(s->cc_op);
5588
                gen_jmp_im(pc_start - s->cs_base);
5589
                gen_helper_fstt_ST0(cpu_A0);
5590
                gen_helper_fpop();
5591
                break;
5592
            case 0x2c: /* frstor mem */
5593
                if (s->cc_op != CC_OP_DYNAMIC)
5594
                    gen_op_set_cc_op(s->cc_op);
5595
                gen_jmp_im(pc_start - s->cs_base);
5596
                gen_helper_frstor(cpu_A0, tcg_const_i32(s->dflag));
5597
                break;
5598
            case 0x2e: /* fnsave mem */
5599
                if (s->cc_op != CC_OP_DYNAMIC)
5600
                    gen_op_set_cc_op(s->cc_op);
5601
                gen_jmp_im(pc_start - s->cs_base);
5602
                gen_helper_fsave(cpu_A0, tcg_const_i32(s->dflag));
5603
                break;
5604
            case 0x2f: /* fnstsw mem */
5605
                gen_helper_fnstsw(cpu_tmp2_i32);
5606
                tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5607
                gen_op_st_T0_A0(OT_WORD + s->mem_index);
5608
                break;
5609
            case 0x3c: /* fbld */
5610
                if (s->cc_op != CC_OP_DYNAMIC)
5611
                    gen_op_set_cc_op(s->cc_op);
5612
                gen_jmp_im(pc_start - s->cs_base);
5613
                gen_helper_fbld_ST0(cpu_A0);
5614
                break;
5615
            case 0x3e: /* fbstp */
5616
                if (s->cc_op != CC_OP_DYNAMIC)
5617
                    gen_op_set_cc_op(s->cc_op);
5618
                gen_jmp_im(pc_start - s->cs_base);
5619
                gen_helper_fbst_ST0(cpu_A0);
5620
                gen_helper_fpop();
5621
                break;
5622
            case 0x3d: /* fildll */
5623
                tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
5624
                                  (s->mem_index >> 2) - 1);
5625
                gen_helper_fildll_ST0(cpu_tmp1_i64);
5626
                break;
5627
            case 0x3f: /* fistpll */
5628
                gen_helper_fistll_ST0(cpu_tmp1_i64);
5629
                tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
5630
                                  (s->mem_index >> 2) - 1);
5631
                gen_helper_fpop();
5632
                break;
5633
            default:
5634
                goto illegal_op;
5635
            }
5636
        } else {
5637
            /* register float ops */
5638
            opreg = rm;
5639

    
5640
            switch(op) {
5641
            case 0x08: /* fld sti */
5642
                gen_helper_fpush();
5643
                gen_helper_fmov_ST0_STN(tcg_const_i32((opreg + 1) & 7));
5644
                break;
5645
            case 0x09: /* fxchg sti */
5646
            case 0x29: /* fxchg4 sti, undocumented op */
5647
            case 0x39: /* fxchg7 sti, undocumented op */
5648
                gen_helper_fxchg_ST0_STN(tcg_const_i32(opreg));
5649
                break;
5650
            case 0x0a: /* grp d9/2 */
5651
                switch(rm) {
5652
                case 0: /* fnop */
5653
                    /* check exceptions (FreeBSD FPU probe) */
5654
                    if (s->cc_op != CC_OP_DYNAMIC)
5655
                        gen_op_set_cc_op(s->cc_op);
5656
                    gen_jmp_im(pc_start - s->cs_base);
5657
                    gen_helper_fwait();
5658
                    break;
5659
                default:
5660
                    goto illegal_op;
5661
                }
5662
                break;
5663
            case 0x0c: /* grp d9/4 */
5664
                switch(rm) {
5665
                case 0: /* fchs */
5666
                    gen_helper_fchs_ST0();
5667
                    break;
5668
                case 1: /* fabs */
5669
                    gen_helper_fabs_ST0();
5670
                    break;
5671
                case 4: /* ftst */
5672
                    gen_helper_fldz_FT0();
5673
                    gen_helper_fcom_ST0_FT0();
5674
                    break;
5675
                case 5: /* fxam */
5676
                    gen_helper_fxam_ST0();
5677
                    break;
5678
                default:
5679
                    goto illegal_op;
5680
                }
5681
                break;
5682
            case 0x0d: /* grp d9/5 */
5683
                {
5684
                    switch(rm) {
5685
                    case 0:
5686
                        gen_helper_fpush();
5687
                        gen_helper_fld1_ST0();
5688
                        break;
5689
                    case 1:
5690
                        gen_helper_fpush();
5691
                        gen_helper_fldl2t_ST0();
5692
                        break;
5693
                    case 2:
5694
                        gen_helper_fpush();
5695
                        gen_helper_fldl2e_ST0();
5696
                        break;
5697
                    case 3:
5698
                        gen_helper_fpush();
5699
                        gen_helper_fldpi_ST0();
5700
                        break;
5701
                    case 4:
5702
                        gen_helper_fpush();
5703
                        gen_helper_fldlg2_ST0();
5704
                        break;
5705
                    case 5:
5706
                        gen_helper_fpush();
5707
                        gen_helper_fldln2_ST0();
5708
                        break;
5709
                    case 6:
5710
                        gen_helper_fpush();
5711
                        gen_helper_fldz_ST0();
5712
                        break;
5713
                    default:
5714
                        goto illegal_op;
5715
                    }
5716
                }
5717
                break;
5718
            case 0x0e: /* grp d9/6 */
5719
                switch(rm) {
5720
                case 0: /* f2xm1 */
5721
                    gen_helper_f2xm1();
5722
                    break;
5723
                case 1: /* fyl2x */
5724
                    gen_helper_fyl2x();
5725
                    break;
5726
                case 2: /* fptan */
5727
                    gen_helper_fptan();
5728
                    break;
5729
                case 3: /* fpatan */
5730
                    gen_helper_fpatan();
5731
                    break;
5732
                case 4: /* fxtract */
5733
                    gen_helper_fxtract();
5734
                    break;
5735
                case 5: /* fprem1 */
5736
                    gen_helper_fprem1();
5737
                    break;
5738
                case 6: /* fdecstp */
5739
                    gen_helper_fdecstp();
5740
                    break;
5741
                default:
5742
                case 7: /* fincstp */
5743
                    gen_helper_fincstp();
5744
                    break;
5745
                }
5746
                break;
5747
            case 0x0f: /* grp d9/7 */
5748
                switch(rm) {
5749
                case 0: /* fprem */
5750
                    gen_helper_fprem();
5751
                    break;
5752
                case 1: /* fyl2xp1 */
5753
                    gen_helper_fyl2xp1();
5754
                    break;
5755
                case 2: /* fsqrt */
5756
                    gen_helper_fsqrt();
5757
                    break;
5758
                case 3: /* fsincos */
5759
                    gen_helper_fsincos();
5760
                    break;
5761
                case 5: /* fscale */
5762
                    gen_helper_fscale();
5763
                    break;
5764
                case 4: /* frndint */
5765
                    gen_helper_frndint();
5766
                    break;
5767
                case 6: /* fsin */
5768
                    gen_helper_fsin();
5769
                    break;
5770
                default:
5771
                case 7: /* fcos */
5772
                    gen_helper_fcos();
5773
                    break;
5774
                }
5775
                break;
5776
            case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
5777
            case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
5778
            case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
5779
                {
5780
                    int op1;
5781

    
5782
                    op1 = op & 7;
5783
                    if (op >= 0x20) {
5784
                        gen_helper_fp_arith_STN_ST0(op1, opreg);
5785
                        if (op >= 0x30)
5786
                            gen_helper_fpop();
5787
                    } else {
5788
                        gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5789
                        gen_helper_fp_arith_ST0_FT0(op1);
5790
                    }
5791
                }
5792
                break;
5793
            case 0x02: /* fcom */
5794
            case 0x22: /* fcom2, undocumented op */
5795
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5796
                gen_helper_fcom_ST0_FT0();
5797
                break;
5798
            case 0x03: /* fcomp */
5799
            case 0x23: /* fcomp3, undocumented op */
5800
            case 0x32: /* fcomp5, undocumented op */
5801
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5802
                gen_helper_fcom_ST0_FT0();
5803
                gen_helper_fpop();
5804
                break;
5805
            case 0x15: /* da/5 */
5806
                switch(rm) {
5807
                case 1: /* fucompp */
5808
                    gen_helper_fmov_FT0_STN(tcg_const_i32(1));
5809
                    gen_helper_fucom_ST0_FT0();
5810
                    gen_helper_fpop();
5811
                    gen_helper_fpop();
5812
                    break;
5813
                default:
5814
                    goto illegal_op;
5815
                }
5816
                break;
5817
            case 0x1c:
5818
                switch(rm) {
5819
                case 0: /* feni (287 only, just do nop here) */
5820
                    break;
5821
                case 1: /* fdisi (287 only, just do nop here) */
5822
                    break;
5823
                case 2: /* fclex */
5824
                    gen_helper_fclex();
5825
                    break;
5826
                case 3: /* fninit */
5827
                    gen_helper_fninit();
5828
                    break;
5829
                case 4: /* fsetpm (287 only, just do nop here) */
5830
                    break;
5831
                default:
5832
                    goto illegal_op;
5833
                }
5834
                break;
5835
            case 0x1d: /* fucomi */
5836
                if (s->cc_op != CC_OP_DYNAMIC)
5837
                    gen_op_set_cc_op(s->cc_op);
5838
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5839
                gen_helper_fucomi_ST0_FT0();
5840
                s->cc_op = CC_OP_EFLAGS;
5841
                break;
5842
            case 0x1e: /* fcomi */
5843
                if (s->cc_op != CC_OP_DYNAMIC)
5844
                    gen_op_set_cc_op(s->cc_op);
5845
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5846
                gen_helper_fcomi_ST0_FT0();
5847
                s->cc_op = CC_OP_EFLAGS;
5848
                break;
5849
            case 0x28: /* ffree sti */
5850
                gen_helper_ffree_STN(tcg_const_i32(opreg));
5851
                break;
5852
            case 0x2a: /* fst sti */
5853
                gen_helper_fmov_STN_ST0(tcg_const_i32(opreg));
5854
                break;
5855
            case 0x2b: /* fstp sti */
5856
            case 0x0b: /* fstp1 sti, undocumented op */
5857
            case 0x3a: /* fstp8 sti, undocumented op */
5858
            case 0x3b: /* fstp9 sti, undocumented op */
5859
                gen_helper_fmov_STN_ST0(tcg_const_i32(opreg));
5860
                gen_helper_fpop();
5861
                break;
5862
            case 0x2c: /* fucom st(i) */
5863
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5864
                gen_helper_fucom_ST0_FT0();
5865
                break;
5866
            case 0x2d: /* fucomp st(i) */
5867
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5868
                gen_helper_fucom_ST0_FT0();
5869
                gen_helper_fpop();
5870
                break;
5871
            case 0x33: /* de/3 */
5872
                switch(rm) {
5873
                case 1: /* fcompp */
5874
                    gen_helper_fmov_FT0_STN(tcg_const_i32(1));
5875
                    gen_helper_fcom_ST0_FT0();
5876
                    gen_helper_fpop();
5877
                    gen_helper_fpop();
5878
                    break;
5879
                default:
5880
                    goto illegal_op;
5881
                }
5882
                break;
5883
            case 0x38: /* ffreep sti, undocumented op */
5884
                gen_helper_ffree_STN(tcg_const_i32(opreg));
5885
                gen_helper_fpop();
5886
                break;
5887
            case 0x3c: /* df/4 */
5888
                switch(rm) {
5889
                case 0:
5890
                    gen_helper_fnstsw(cpu_tmp2_i32);
5891
                    tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5892
                    gen_op_mov_reg_T0(OT_WORD, R_EAX);
5893
                    break;
5894
                default:
5895
                    goto illegal_op;
5896
                }
5897
                break;
5898
            case 0x3d: /* fucomip */
5899
                if (s->cc_op != CC_OP_DYNAMIC)
5900
                    gen_op_set_cc_op(s->cc_op);
5901
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5902
                gen_helper_fucomi_ST0_FT0();
5903
                gen_helper_fpop();
5904
                s->cc_op = CC_OP_EFLAGS;
5905
                break;
5906
            case 0x3e: /* fcomip */
5907
                if (s->cc_op != CC_OP_DYNAMIC)
5908
                    gen_op_set_cc_op(s->cc_op);
5909
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5910
                gen_helper_fcomi_ST0_FT0();
5911
                gen_helper_fpop();
5912
                s->cc_op = CC_OP_EFLAGS;
5913
                break;
5914
            case 0x10 ... 0x13: /* fcmovxx */
5915
            case 0x18 ... 0x1b:
5916
                {
5917
                    int op1, l1;
5918
                    static const uint8_t fcmov_cc[8] = {
5919
                        (JCC_B << 1),
5920
                        (JCC_Z << 1),
5921
                        (JCC_BE << 1),
5922
                        (JCC_P << 1),
5923
                    };
5924
                    op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
5925
                    l1 = gen_new_label();
5926
                    gen_jcc1(s, s->cc_op, op1, l1);
5927
                    gen_helper_fmov_ST0_STN(tcg_const_i32(opreg));
5928
                    gen_set_label(l1);
5929
                }
5930
                break;
5931
            default:
5932
                goto illegal_op;
5933
            }
5934
        }
5935
        break;
5936
        /************************/
5937
        /* string ops */
5938

    
5939
    case 0xa4: /* movsS */
5940
    case 0xa5:
5941
        if ((b & 1) == 0)
5942
            ot = OT_BYTE;
5943
        else
5944
            ot = dflag + OT_WORD;
5945

    
5946
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5947
            gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5948
        } else {
5949
            gen_movs(s, ot);
5950
        }
5951
        break;
5952

    
5953
    case 0xaa: /* stosS */
5954
    case 0xab:
5955
        if ((b & 1) == 0)
5956
            ot = OT_BYTE;
5957
        else
5958
            ot = dflag + OT_WORD;
5959

    
5960
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5961
            gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5962
        } else {
5963
            gen_stos(s, ot);
5964
        }
5965
        break;
5966
    case 0xac: /* lodsS */
5967
    case 0xad:
5968
        if ((b & 1) == 0)
5969
            ot = OT_BYTE;
5970
        else
5971
            ot = dflag + OT_WORD;
5972
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5973
            gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5974
        } else {
5975
            gen_lods(s, ot);
5976
        }
5977
        break;
5978
    case 0xae: /* scasS */
5979
    case 0xaf:
5980
        if ((b & 1) == 0)
5981
            ot = OT_BYTE;
5982
        else
5983
            ot = dflag + OT_WORD;
5984
        if (prefixes & PREFIX_REPNZ) {
5985
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
5986
        } else if (prefixes & PREFIX_REPZ) {
5987
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
5988
        } else {
5989
            gen_scas(s, ot);
5990
            s->cc_op = CC_OP_SUBB + ot;
5991
        }
5992
        break;
5993

    
5994
    case 0xa6: /* cmpsS */
5995
    case 0xa7:
5996
        if ((b & 1) == 0)
5997
            ot = OT_BYTE;
5998
        else
5999
            ot = dflag + OT_WORD;
6000
        if (prefixes & PREFIX_REPNZ) {
6001
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6002
        } else if (prefixes & PREFIX_REPZ) {
6003
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6004
        } else {
6005
            gen_cmps(s, ot);
6006
            s->cc_op = CC_OP_SUBB + ot;
6007
        }
6008
        break;
6009
    case 0x6c: /* insS */
6010
    case 0x6d:
6011
        if ((b & 1) == 0)
6012
            ot = OT_BYTE;
6013
        else
6014
            ot = dflag ? OT_LONG : OT_WORD;
6015
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6016
        gen_op_andl_T0_ffff();
6017
        gen_check_io(s, ot, pc_start - s->cs_base, 
6018
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
6019
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6020
            gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6021
        } else {
6022
            gen_ins(s, ot);
6023
            if (use_icount) {
6024
                gen_jmp(s, s->pc - s->cs_base);
6025
            }
6026
        }
6027
        break;
6028
    case 0x6e: /* outsS */
6029
    case 0x6f:
6030
        if ((b & 1) == 0)
6031
            ot = OT_BYTE;
6032
        else
6033
            ot = dflag ? OT_LONG : OT_WORD;
6034
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6035
        gen_op_andl_T0_ffff();
6036
        gen_check_io(s, ot, pc_start - s->cs_base,
6037
                     svm_is_rep(prefixes) | 4);
6038
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6039
            gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6040
        } else {
6041
            gen_outs(s, ot);
6042
            if (use_icount) {
6043
                gen_jmp(s, s->pc - s->cs_base);
6044
            }
6045
        }
6046
        break;
6047

    
6048
        /************************/
6049
        /* port I/O */
6050

    
6051
    case 0xe4:
6052
    case 0xe5:
6053
        if ((b & 1) == 0)
6054
            ot = OT_BYTE;
6055
        else
6056
            ot = dflag ? OT_LONG : OT_WORD;
6057
        val = ldub_code(s->pc++);
6058
        gen_op_movl_T0_im(val);
6059
        gen_check_io(s, ot, pc_start - s->cs_base,
6060
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6061
        if (use_icount)
6062
            gen_io_start();
6063
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6064
        gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
6065
        gen_op_mov_reg_T1(ot, R_EAX);
6066
        if (use_icount) {
6067
            gen_io_end();
6068
            gen_jmp(s, s->pc - s->cs_base);
6069
        }
6070
        break;
6071
    case 0xe6:
6072
    case 0xe7:
6073
        if ((b & 1) == 0)
6074
            ot = OT_BYTE;
6075
        else
6076
            ot = dflag ? OT_LONG : OT_WORD;
6077
        val = ldub_code(s->pc++);
6078
        gen_op_movl_T0_im(val);
6079
        gen_check_io(s, ot, pc_start - s->cs_base,
6080
                     svm_is_rep(prefixes));
6081
        gen_op_mov_TN_reg(ot, 1, R_EAX);
6082

    
6083
        if (use_icount)
6084
            gen_io_start();
6085
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6086
        tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
6087
        tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
6088
        gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6089
        if (use_icount) {
6090
            gen_io_end();
6091
            gen_jmp(s, s->pc - s->cs_base);
6092
        }
6093
        break;
6094
    case 0xec:
6095
    case 0xed:
6096
        if ((b & 1) == 0)
6097
            ot = OT_BYTE;
6098
        else
6099
            ot = dflag ? OT_LONG : OT_WORD;
6100
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6101
        gen_op_andl_T0_ffff();
6102
        gen_check_io(s, ot, pc_start - s->cs_base,
6103
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6104
        if (use_icount)
6105
            gen_io_start();
6106
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6107
        gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
6108
        gen_op_mov_reg_T1(ot, R_EAX);
6109
        if (use_icount) {
6110
            gen_io_end();
6111
            gen_jmp(s, s->pc - s->cs_base);
6112
        }
6113
        break;
6114
    case 0xee:
6115
    case 0xef:
6116
        if ((b & 1) == 0)
6117
            ot = OT_BYTE;
6118
        else
6119
            ot = dflag ? OT_LONG : OT_WORD;
6120
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6121
        gen_op_andl_T0_ffff();
6122
        gen_check_io(s, ot, pc_start - s->cs_base,
6123
                     svm_is_rep(prefixes));
6124
        gen_op_mov_TN_reg(ot, 1, R_EAX);
6125

    
6126
        if (use_icount)
6127
            gen_io_start();
6128
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6129
        tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
6130
        tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
6131
        gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6132
        if (use_icount) {
6133
            gen_io_end();
6134
            gen_jmp(s, s->pc - s->cs_base);
6135
        }
6136
        break;
6137

    
6138
        /************************/
6139
        /* control */
6140
    case 0xc2: /* ret im */
6141
        val = ldsw_code(s->pc);
6142
        s->pc += 2;
6143
        gen_pop_T0(s);
6144
        if (CODE64(s) && s->dflag)
6145
            s->dflag = 2;
6146
        gen_stack_update(s, val + (2 << s->dflag));
6147
        if (s->dflag == 0)
6148
            gen_op_andl_T0_ffff();
6149
        gen_op_jmp_T0();
6150
        gen_eob(s);
6151
        break;
6152
    case 0xc3: /* ret */
6153
        gen_pop_T0(s);
6154
        gen_pop_update(s);
6155
        if (s->dflag == 0)
6156
            gen_op_andl_T0_ffff();
6157
        gen_op_jmp_T0();
6158
        gen_eob(s);
6159
        break;
6160
    case 0xca: /* lret im */
6161
        val = ldsw_code(s->pc);
6162
        s->pc += 2;
6163
    do_lret:
6164
        if (s->pe && !s->vm86) {
6165
            if (s->cc_op != CC_OP_DYNAMIC)
6166
                gen_op_set_cc_op(s->cc_op);
6167
            gen_jmp_im(pc_start - s->cs_base);
6168
            gen_helper_lret_protected(tcg_const_i32(s->dflag),
6169
                                      tcg_const_i32(val));
6170
        } else {
6171
            gen_stack_A0(s);
6172
            /* pop offset */
6173
            gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
6174
            if (s->dflag == 0)
6175
                gen_op_andl_T0_ffff();
6176
            /* NOTE: keeping EIP updated is not a problem in case of
6177
               exception */
6178
            gen_op_jmp_T0();
6179
            /* pop selector */
6180
            gen_op_addl_A0_im(2 << s->dflag);
6181
            gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
6182
            gen_op_movl_seg_T0_vm(R_CS);
6183
            /* add stack offset */
6184
            gen_stack_update(s, val + (4 << s->dflag));
6185
        }
6186
        gen_eob(s);
6187
        break;
6188
    case 0xcb: /* lret */
6189
        val = 0;
6190
        goto do_lret;
6191
    case 0xcf: /* iret */
6192
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
6193
        if (!s->pe) {
6194
            /* real mode */
6195
            gen_helper_iret_real(tcg_const_i32(s->dflag));
6196
            s->cc_op = CC_OP_EFLAGS;
6197
        } else if (s->vm86) {
6198
            if (s->iopl != 3) {
6199
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6200
            } else {
6201
                gen_helper_iret_real(tcg_const_i32(s->dflag));
6202
                s->cc_op = CC_OP_EFLAGS;
6203
            }
6204
        } else {
6205
            if (s->cc_op != CC_OP_DYNAMIC)
6206
                gen_op_set_cc_op(s->cc_op);
6207
            gen_jmp_im(pc_start - s->cs_base);
6208
            gen_helper_iret_protected(tcg_const_i32(s->dflag), 
6209
                                      tcg_const_i32(s->pc - s->cs_base));
6210
            s->cc_op = CC_OP_EFLAGS;
6211
        }
6212
        gen_eob(s);
6213
        break;
6214
    case 0xe8: /* call im */
6215
        {
6216
            if (dflag)
6217
                tval = (int32_t)insn_get(s, OT_LONG);
6218
            else
6219
                tval = (int16_t)insn_get(s, OT_WORD);
6220
            next_eip = s->pc - s->cs_base;
6221
            tval += next_eip;
6222
            if (s->dflag == 0)
6223
                tval &= 0xffff;
6224
            gen_movtl_T0_im(next_eip);
6225
            gen_push_T0(s);
6226
            gen_jmp(s, tval);
6227
        }
6228
        break;
6229
    case 0x9a: /* lcall im */
6230
        {
6231
            unsigned int selector, offset;
6232

    
6233
            if (CODE64(s))
6234
                goto illegal_op;
6235
            ot = dflag ? OT_LONG : OT_WORD;
6236
            offset = insn_get(s, ot);
6237
            selector = insn_get(s, OT_WORD);
6238

    
6239
            gen_op_movl_T0_im(selector);
6240
            gen_op_movl_T1_imu(offset);
6241
        }
6242
        goto do_lcall;
6243
    case 0xe9: /* jmp im */
6244
        if (dflag)
6245
            tval = (int32_t)insn_get(s, OT_LONG);
6246
        else
6247
            tval = (int16_t)insn_get(s, OT_WORD);
6248
        tval += s->pc - s->cs_base;
6249
        if (s->dflag == 0)
6250
            tval &= 0xffff;
6251
        else if(!CODE64(s))
6252
            tval &= 0xffffffff;
6253
        gen_jmp(s, tval);
6254
        break;
6255
    case 0xea: /* ljmp im */
6256
        {
6257
            unsigned int selector, offset;
6258

    
6259
            if (CODE64(s))
6260
                goto illegal_op;
6261
            ot = dflag ? OT_LONG : OT_WORD;
6262
            offset = insn_get(s, ot);
6263
            selector = insn_get(s, OT_WORD);
6264

    
6265
            gen_op_movl_T0_im(selector);
6266
            gen_op_movl_T1_imu(offset);
6267
        }
6268
        goto do_ljmp;
6269
    case 0xeb: /* jmp Jb */
6270
        tval = (int8_t)insn_get(s, OT_BYTE);
6271
        tval += s->pc - s->cs_base;
6272
        if (s->dflag == 0)
6273
            tval &= 0xffff;
6274
        gen_jmp(s, tval);
6275
        break;
6276
    case 0x70 ... 0x7f: /* jcc Jb */
6277
        tval = (int8_t)insn_get(s, OT_BYTE);
6278
        goto do_jcc;
6279
    case 0x180 ... 0x18f: /* jcc Jv */
6280
        if (dflag) {
6281
            tval = (int32_t)insn_get(s, OT_LONG);
6282
        } else {
6283
            tval = (int16_t)insn_get(s, OT_WORD);
6284
        }
6285
    do_jcc:
6286
        next_eip = s->pc - s->cs_base;
6287
        tval += next_eip;
6288
        if (s->dflag == 0)
6289
            tval &= 0xffff;
6290
        gen_jcc(s, b, tval, next_eip);
6291
        break;
6292

    
6293
    case 0x190 ... 0x19f: /* setcc Gv */
6294
        modrm = ldub_code(s->pc++);
6295
        gen_setcc(s, b);
6296
        gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
6297
        break;
6298
    case 0x140 ... 0x14f: /* cmov Gv, Ev */
6299
        {
6300
            int l1;
6301
            TCGv t0;
6302

    
6303
            ot = dflag + OT_WORD;
6304
            modrm = ldub_code(s->pc++);
6305
            reg = ((modrm >> 3) & 7) | rex_r;
6306
            mod = (modrm >> 6) & 3;
6307
            t0 = tcg_temp_local_new();
6308
            if (mod != 3) {
6309
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6310
                gen_op_ld_v(ot + s->mem_index, t0, cpu_A0);
6311
            } else {
6312
                rm = (modrm & 7) | REX_B(s);
6313
                gen_op_mov_v_reg(ot, t0, rm);
6314
            }
6315
#ifdef TARGET_X86_64
6316
            if (ot == OT_LONG) {
6317
                /* XXX: specific Intel behaviour ? */
6318
                l1 = gen_new_label();
6319
                gen_jcc1(s, s->cc_op, b ^ 1, l1);
6320
                tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
6321
                gen_set_label(l1);
6322
                tcg_gen_movi_tl(cpu_tmp0, 0);
6323
                tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_LH_OFFSET);
6324
            } else
6325
#endif
6326
            {
6327
                l1 = gen_new_label();
6328
                gen_jcc1(s, s->cc_op, b ^ 1, l1);
6329
                gen_op_mov_reg_v(ot, reg, t0);
6330
                gen_set_label(l1);
6331
            }
6332
            tcg_temp_free(t0);
6333
        }
6334
        break;
6335

    
6336
        /************************/
6337
        /* flags */
6338
    case 0x9c: /* pushf */
6339
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
6340
        if (s->vm86 && s->iopl != 3) {
6341
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6342
        } else {
6343
            if (s->cc_op != CC_OP_DYNAMIC)
6344
                gen_op_set_cc_op(s->cc_op);
6345
            gen_helper_read_eflags(cpu_T[0]);
6346
            gen_push_T0(s);
6347
        }
6348
        break;
6349
    case 0x9d: /* popf */
6350
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
6351
        if (s->vm86 && s->iopl != 3) {
6352
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6353
        } else {
6354
            gen_pop_T0(s);
6355
            if (s->cpl == 0) {
6356
                if (s->dflag) {
6357
                    gen_helper_write_eflags(cpu_T[0],
6358
                                       tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK)));
6359
                } else {
6360
                    gen_helper_write_eflags(cpu_T[0],
6361
                                       tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff));
6362
                }
6363
            } else {
6364
                if (s->cpl <= s->iopl) {
6365
                    if (s->dflag) {
6366
                        gen_helper_write_eflags(cpu_T[0],
6367
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK)));
6368
                    } else {
6369
                        gen_helper_write_eflags(cpu_T[0],
6370
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff));
6371
                    }
6372
                } else {
6373
                    if (s->dflag) {
6374
                        gen_helper_write_eflags(cpu_T[0],
6375
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK)));
6376
                    } else {
6377
                        gen_helper_write_eflags(cpu_T[0],
6378
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff));
6379
                    }
6380
                }
6381
            }
6382
            gen_pop_update(s);
6383
            s->cc_op = CC_OP_EFLAGS;
6384
            /* abort translation because TF flag may change */
6385
            gen_jmp_im(s->pc - s->cs_base);
6386
            gen_eob(s);
6387
        }
6388
        break;
6389
    case 0x9e: /* sahf */
6390
        if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6391
            goto illegal_op;
6392
        gen_op_mov_TN_reg(OT_BYTE, 0, R_AH);
6393
        if (s->cc_op != CC_OP_DYNAMIC)
6394
            gen_op_set_cc_op(s->cc_op);
6395
        gen_compute_eflags(cpu_cc_src);
6396
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
6397
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], CC_S | CC_Z | CC_A | CC_P | CC_C);
6398
        tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T[0]);
6399
        s->cc_op = CC_OP_EFLAGS;
6400
        break;
6401
    case 0x9f: /* lahf */
6402
        if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6403
            goto illegal_op;
6404
        if (s->cc_op != CC_OP_DYNAMIC)
6405
            gen_op_set_cc_op(s->cc_op);
6406
        gen_compute_eflags(cpu_T[0]);
6407
        /* Note: gen_compute_eflags() only gives the condition codes */
6408
        tcg_gen_ori_tl(cpu_T[0], cpu_T[0], 0x02);
6409
        gen_op_mov_reg_T0(OT_BYTE, R_AH);
6410
        break;
6411
    case 0xf5: /* cmc */
6412
        if (s->cc_op != CC_OP_DYNAMIC)
6413
            gen_op_set_cc_op(s->cc_op);
6414
        gen_compute_eflags(cpu_cc_src);
6415
        tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6416
        s->cc_op = CC_OP_EFLAGS;
6417
        break;
6418
    case 0xf8: /* clc */
6419
        if (s->cc_op != CC_OP_DYNAMIC)
6420
            gen_op_set_cc_op(s->cc_op);
6421
        gen_compute_eflags(cpu_cc_src);
6422
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
6423
        s->cc_op = CC_OP_EFLAGS;
6424
        break;
6425
    case 0xf9: /* stc */
6426
        if (s->cc_op != CC_OP_DYNAMIC)
6427
            gen_op_set_cc_op(s->cc_op);
6428
        gen_compute_eflags(cpu_cc_src);
6429
        tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6430
        s->cc_op = CC_OP_EFLAGS;
6431
        break;
6432
    case 0xfc: /* cld */
6433
        tcg_gen_movi_i32(cpu_tmp2_i32, 1);
6434
        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUState, df));
6435
        break;
6436
    case 0xfd: /* std */
6437
        tcg_gen_movi_i32(cpu_tmp2_i32, -1);
6438
        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUState, df));
6439
        break;
6440

    
6441
        /************************/
6442
        /* bit operations */
6443
    case 0x1ba: /* bt/bts/btr/btc Gv, im */
6444
        ot = dflag + OT_WORD;
6445
        modrm = ldub_code(s->pc++);
6446
        op = (modrm >> 3) & 7;
6447
        mod = (modrm >> 6) & 3;
6448
        rm = (modrm & 7) | REX_B(s);
6449
        if (mod != 3) {
6450
            s->rip_offset = 1;
6451
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6452
            gen_op_ld_T0_A0(ot + s->mem_index);
6453
        } else {
6454
            gen_op_mov_TN_reg(ot, 0, rm);
6455
        }
6456
        /* load shift */
6457
        val = ldub_code(s->pc++);
6458
        gen_op_movl_T1_im(val);
6459
        if (op < 4)
6460
            goto illegal_op;
6461
        op -= 4;
6462
        goto bt_op;
6463
    case 0x1a3: /* bt Gv, Ev */
6464
        op = 0;
6465
        goto do_btx;
6466
    case 0x1ab: /* bts */
6467
        op = 1;
6468
        goto do_btx;
6469
    case 0x1b3: /* btr */
6470
        op = 2;
6471
        goto do_btx;
6472
    case 0x1bb: /* btc */
6473
        op = 3;
6474
    do_btx:
6475
        ot = dflag + OT_WORD;
6476
        modrm = ldub_code(s->pc++);
6477
        reg = ((modrm >> 3) & 7) | rex_r;
6478
        mod = (modrm >> 6) & 3;
6479
        rm = (modrm & 7) | REX_B(s);
6480
        gen_op_mov_TN_reg(OT_LONG, 1, reg);
6481
        if (mod != 3) {
6482
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6483
            /* specific case: we need to add a displacement */
6484
            gen_exts(ot, cpu_T[1]);
6485
            tcg_gen_sari_tl(cpu_tmp0, cpu_T[1], 3 + ot);
6486
            tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
6487
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
6488
            gen_op_ld_T0_A0(ot + s->mem_index);
6489
        } else {
6490
            gen_op_mov_TN_reg(ot, 0, rm);
6491
        }
6492
    bt_op:
6493
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], (1 << (3 + ot)) - 1);
6494
        switch(op) {
6495
        case 0:
6496
            tcg_gen_shr_tl(cpu_cc_src, cpu_T[0], cpu_T[1]);
6497
            tcg_gen_movi_tl(cpu_cc_dst, 0);
6498
            break;
6499
        case 1:
6500
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6501
            tcg_gen_movi_tl(cpu_tmp0, 1);
6502
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6503
            tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6504
            break;
6505
        case 2:
6506
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6507
            tcg_gen_movi_tl(cpu_tmp0, 1);
6508
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6509
            tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
6510
            tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6511
            break;
6512
        default:
6513
        case 3:
6514
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6515
            tcg_gen_movi_tl(cpu_tmp0, 1);
6516
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6517
            tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6518
            break;
6519
        }
6520
        s->cc_op = CC_OP_SARB + ot;
6521
        if (op != 0) {
6522
            if (mod != 3)
6523
                gen_op_st_T0_A0(ot + s->mem_index);
6524
            else
6525
                gen_op_mov_reg_T0(ot, rm);
6526
            tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
6527
            tcg_gen_movi_tl(cpu_cc_dst, 0);
6528
        }
6529
        break;
6530
    case 0x1bc: /* bsf */
6531
    case 0x1bd: /* bsr */
6532
        {
6533
            int label1;
6534
            TCGv t0;
6535

    
6536
            ot = dflag + OT_WORD;
6537
            modrm = ldub_code(s->pc++);
6538
            reg = ((modrm >> 3) & 7) | rex_r;
6539
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
6540
            gen_extu(ot, cpu_T[0]);
6541
            label1 = gen_new_label();
6542
            tcg_gen_movi_tl(cpu_cc_dst, 0);
6543
            t0 = tcg_temp_local_new();
6544
            tcg_gen_mov_tl(t0, cpu_T[0]);
6545
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, label1);
6546
            if (b & 1) {
6547
                gen_helper_bsr(cpu_T[0], t0);
6548
            } else {
6549
                gen_helper_bsf(cpu_T[0], t0);
6550
            }
6551
            gen_op_mov_reg_T0(ot, reg);
6552
            tcg_gen_movi_tl(cpu_cc_dst, 1);
6553
            gen_set_label(label1);
6554
            tcg_gen_discard_tl(cpu_cc_src);
6555
            s->cc_op = CC_OP_LOGICB + ot;
6556
            tcg_temp_free(t0);
6557
        }
6558
        break;
6559
        /************************/
6560
        /* bcd */
6561
    case 0x27: /* daa */
6562
        if (CODE64(s))
6563
            goto illegal_op;
6564
        if (s->cc_op != CC_OP_DYNAMIC)
6565
            gen_op_set_cc_op(s->cc_op);
6566
        gen_helper_daa();
6567
        s->cc_op = CC_OP_EFLAGS;
6568
        break;
6569
    case 0x2f: /* das */
6570
        if (CODE64(s))
6571
            goto illegal_op;
6572
        if (s->cc_op != CC_OP_DYNAMIC)
6573
            gen_op_set_cc_op(s->cc_op);
6574
        gen_helper_das();
6575
        s->cc_op = CC_OP_EFLAGS;
6576
        break;
6577
    case 0x37: /* aaa */
6578
        if (CODE64(s))
6579
            goto illegal_op;
6580
        if (s->cc_op != CC_OP_DYNAMIC)
6581
            gen_op_set_cc_op(s->cc_op);
6582
        gen_helper_aaa();
6583
        s->cc_op = CC_OP_EFLAGS;
6584
        break;
6585
    case 0x3f: /* aas */
6586
        if (CODE64(s))
6587
            goto illegal_op;
6588
        if (s->cc_op != CC_OP_DYNAMIC)
6589
            gen_op_set_cc_op(s->cc_op);
6590
        gen_helper_aas();
6591
        s->cc_op = CC_OP_EFLAGS;
6592
        break;
6593
    case 0xd4: /* aam */
6594
        if (CODE64(s))
6595
            goto illegal_op;
6596
        val = ldub_code(s->pc++);
6597
        if (val == 0) {
6598
            gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
6599
        } else {
6600
            gen_helper_aam(tcg_const_i32(val));
6601
            s->cc_op = CC_OP_LOGICB;
6602
        }
6603
        break;
6604
    case 0xd5: /* aad */
6605
        if (CODE64(s))
6606
            goto illegal_op;
6607
        val = ldub_code(s->pc++);
6608
        gen_helper_aad(tcg_const_i32(val));
6609
        s->cc_op = CC_OP_LOGICB;
6610
        break;
6611
        /************************/
6612
        /* misc */
6613
    case 0x90: /* nop */
6614
        /* XXX: xchg + rex handling */
6615
        /* XXX: correct lock test for all insn */
6616
        if (prefixes & PREFIX_LOCK)
6617
            goto illegal_op;
6618
        if (prefixes & PREFIX_REPZ) {
6619
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_PAUSE);
6620
        }
6621
        break;
6622
    case 0x9b: /* fwait */
6623
        if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
6624
            (HF_MP_MASK | HF_TS_MASK)) {
6625
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6626
        } else {
6627
            if (s->cc_op != CC_OP_DYNAMIC)
6628
                gen_op_set_cc_op(s->cc_op);
6629
            gen_jmp_im(pc_start - s->cs_base);
6630
            gen_helper_fwait();
6631
        }
6632
        break;
6633
    case 0xcc: /* int3 */
6634
        gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
6635
        break;
6636
    case 0xcd: /* int N */
6637
        val = ldub_code(s->pc++);
6638
        if (s->vm86 && s->iopl != 3) {
6639
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6640
        } else {
6641
            gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
6642
        }
6643
        break;
6644
    case 0xce: /* into */
6645
        if (CODE64(s))
6646
            goto illegal_op;
6647
        if (s->cc_op != CC_OP_DYNAMIC)
6648
            gen_op_set_cc_op(s->cc_op);
6649
        gen_jmp_im(pc_start - s->cs_base);
6650
        gen_helper_into(tcg_const_i32(s->pc - pc_start));
6651
        break;
6652
#ifdef WANT_ICEBP
6653
    case 0xf1: /* icebp (undocumented, exits to external debugger) */
6654
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
6655
#if 1
6656
        gen_debug(s, pc_start - s->cs_base);
6657
#else
6658
        /* start debug */
6659
        tb_flush(cpu_single_env);
6660
        cpu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
6661
#endif
6662
        break;
6663
#endif
6664
    case 0xfa: /* cli */
6665
        if (!s->vm86) {
6666
            if (s->cpl <= s->iopl) {
6667
                gen_helper_cli();
6668
            } else {
6669
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6670
            }
6671
        } else {
6672
            if (s->iopl == 3) {
6673
                gen_helper_cli();
6674
            } else {
6675
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6676
            }
6677
        }
6678
        break;
6679
    case 0xfb: /* sti */
6680
        if (!s->vm86) {
6681
            if (s->cpl <= s->iopl) {
6682
            gen_sti:
6683
                gen_helper_sti();
6684
                /* interruptions are enabled only the first insn after sti */
6685
                /* If several instructions disable interrupts, only the
6686
                   _first_ does it */
6687
                if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
6688
                    gen_helper_set_inhibit_irq();
6689
                /* give a chance to handle pending irqs */
6690
                gen_jmp_im(s->pc - s->cs_base);
6691
                gen_eob(s);
6692
            } else {
6693
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6694
            }
6695
        } else {
6696
            if (s->iopl == 3) {
6697
                goto gen_sti;
6698
            } else {
6699
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6700
            }
6701
        }
6702
        break;
6703
    case 0x62: /* bound */
6704
        if (CODE64(s))
6705
            goto illegal_op;
6706
        ot = dflag ? OT_LONG : OT_WORD;
6707
        modrm = ldub_code(s->pc++);
6708
        reg = (modrm >> 3) & 7;
6709
        mod = (modrm >> 6) & 3;
6710
        if (mod == 3)
6711
            goto illegal_op;
6712
        gen_op_mov_TN_reg(ot, 0, reg);
6713
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6714
        gen_jmp_im(pc_start - s->cs_base);
6715
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6716
        if (ot == OT_WORD)
6717
            gen_helper_boundw(cpu_A0, cpu_tmp2_i32);
6718
        else
6719
            gen_helper_boundl(cpu_A0, cpu_tmp2_i32);
6720
        break;
6721
    case 0x1c8 ... 0x1cf: /* bswap reg */
6722
        reg = (b & 7) | REX_B(s);
6723
#ifdef TARGET_X86_64
6724
        if (dflag == 2) {
6725
            gen_op_mov_TN_reg(OT_QUAD, 0, reg);
6726
            tcg_gen_bswap64_i64(cpu_T[0], cpu_T[0]);
6727
            gen_op_mov_reg_T0(OT_QUAD, reg);
6728
        } else
6729
#endif
6730
        {
6731
            gen_op_mov_TN_reg(OT_LONG, 0, reg);
6732
            tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
6733
            tcg_gen_bswap32_tl(cpu_T[0], cpu_T[0]);
6734
            gen_op_mov_reg_T0(OT_LONG, reg);
6735
        }
6736
        break;
6737
    case 0xd6: /* salc */
6738
        if (CODE64(s))
6739
            goto illegal_op;
6740
        if (s->cc_op != CC_OP_DYNAMIC)
6741
            gen_op_set_cc_op(s->cc_op);
6742
        gen_compute_eflags_c(cpu_T[0]);
6743
        tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
6744
        gen_op_mov_reg_T0(OT_BYTE, R_EAX);
6745
        break;
6746
    case 0xe0: /* loopnz */
6747
    case 0xe1: /* loopz */
6748
    case 0xe2: /* loop */
6749
    case 0xe3: /* jecxz */
6750
        {
6751
            int l1, l2, l3;
6752

    
6753
            tval = (int8_t)insn_get(s, OT_BYTE);
6754
            next_eip = s->pc - s->cs_base;
6755
            tval += next_eip;
6756
            if (s->dflag == 0)
6757
                tval &= 0xffff;
6758

    
6759
            l1 = gen_new_label();
6760
            l2 = gen_new_label();
6761
            l3 = gen_new_label();
6762
            b &= 3;
6763
            switch(b) {
6764
            case 0: /* loopnz */
6765
            case 1: /* loopz */
6766
                if (s->cc_op != CC_OP_DYNAMIC)
6767
                    gen_op_set_cc_op(s->cc_op);
6768
                gen_op_add_reg_im(s->aflag, R_ECX, -1);
6769
                gen_op_jz_ecx(s->aflag, l3);
6770
                gen_compute_eflags(cpu_tmp0);
6771
                tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_Z);
6772
                if (b == 0) {
6773
                    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
6774
                } else {
6775
                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, l1);
6776
                }
6777
                break;
6778
            case 2: /* loop */
6779
                gen_op_add_reg_im(s->aflag, R_ECX, -1);
6780
                gen_op_jnz_ecx(s->aflag, l1);
6781
                break;
6782
            default:
6783
            case 3: /* jcxz */
6784
                gen_op_jz_ecx(s->aflag, l1);
6785
                break;
6786
            }
6787

    
6788
            gen_set_label(l3);
6789
            gen_jmp_im(next_eip);
6790
            tcg_gen_br(l2);
6791

    
6792
            gen_set_label(l1);
6793
            gen_jmp_im(tval);
6794
            gen_set_label(l2);
6795
            gen_eob(s);
6796
        }
6797
        break;
6798
    case 0x130: /* wrmsr */
6799
    case 0x132: /* rdmsr */
6800
        if (s->cpl != 0) {
6801
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6802
        } else {
6803
            if (s->cc_op != CC_OP_DYNAMIC)
6804
                gen_op_set_cc_op(s->cc_op);
6805
            gen_jmp_im(pc_start - s->cs_base);
6806
            if (b & 2) {
6807
                gen_helper_rdmsr();
6808
            } else {
6809
                gen_helper_wrmsr();
6810
            }
6811
        }
6812
        break;
6813
    case 0x131: /* rdtsc */
6814
        if (s->cc_op != CC_OP_DYNAMIC)
6815
            gen_op_set_cc_op(s->cc_op);
6816
        gen_jmp_im(pc_start - s->cs_base);
6817
        if (use_icount)
6818
            gen_io_start();
6819
        gen_helper_rdtsc();
6820
        if (use_icount) {
6821
            gen_io_end();
6822
            gen_jmp(s, s->pc - s->cs_base);
6823
        }
6824
        break;
6825
    case 0x133: /* rdpmc */
6826
        if (s->cc_op != CC_OP_DYNAMIC)
6827
            gen_op_set_cc_op(s->cc_op);
6828
        gen_jmp_im(pc_start - s->cs_base);
6829
        gen_helper_rdpmc();
6830
        break;
6831
    case 0x134: /* sysenter */
6832
        /* For Intel SYSENTER is valid on 64-bit */
6833
        if (CODE64(s) && cpu_single_env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
6834
            goto illegal_op;
6835
        if (!s->pe) {
6836
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6837
        } else {
6838
            if (s->cc_op != CC_OP_DYNAMIC) {
6839
                gen_op_set_cc_op(s->cc_op);
6840
                s->cc_op = CC_OP_DYNAMIC;
6841
            }
6842
            gen_jmp_im(pc_start - s->cs_base);
6843
            gen_helper_sysenter();
6844
            gen_eob(s);
6845
        }
6846
        break;
6847
    case 0x135: /* sysexit */
6848
        /* For Intel SYSEXIT is valid on 64-bit */
6849
        if (CODE64(s) && cpu_single_env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
6850
            goto illegal_op;
6851
        if (!s->pe) {
6852
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6853
        } else {
6854
            if (s->cc_op != CC_OP_DYNAMIC) {
6855
                gen_op_set_cc_op(s->cc_op);
6856
                s->cc_op = CC_OP_DYNAMIC;
6857
            }
6858
            gen_jmp_im(pc_start - s->cs_base);
6859
            gen_helper_sysexit(tcg_const_i32(dflag));
6860
            gen_eob(s);
6861
        }
6862
        break;
6863
#ifdef TARGET_X86_64
6864
    case 0x105: /* syscall */
6865
        /* XXX: is it usable in real mode ? */
6866
        if (s->cc_op != CC_OP_DYNAMIC) {
6867
            gen_op_set_cc_op(s->cc_op);
6868
            s->cc_op = CC_OP_DYNAMIC;
6869
        }
6870
        gen_jmp_im(pc_start - s->cs_base);
6871
        gen_helper_syscall(tcg_const_i32(s->pc - pc_start));
6872
        gen_eob(s);
6873
        break;
6874
    case 0x107: /* sysret */
6875
        if (!s->pe) {
6876
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6877
        } else {
6878
            if (s->cc_op != CC_OP_DYNAMIC) {
6879
                gen_op_set_cc_op(s->cc_op);
6880
                s->cc_op = CC_OP_DYNAMIC;
6881
            }
6882
            gen_jmp_im(pc_start - s->cs_base);
6883
            gen_helper_sysret(tcg_const_i32(s->dflag));
6884
            /* condition codes are modified only in long mode */
6885
            if (s->lma)
6886
                s->cc_op = CC_OP_EFLAGS;
6887
            gen_eob(s);
6888
        }
6889
        break;
6890
#endif
6891
    case 0x1a2: /* cpuid */
6892
        if (s->cc_op != CC_OP_DYNAMIC)
6893
            gen_op_set_cc_op(s->cc_op);
6894
        gen_jmp_im(pc_start - s->cs_base);
6895
        gen_helper_cpuid();
6896
        break;
6897
    case 0xf4: /* hlt */
6898
        if (s->cpl != 0) {
6899
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6900
        } else {
6901
            if (s->cc_op != CC_OP_DYNAMIC)
6902
                gen_op_set_cc_op(s->cc_op);
6903
            gen_jmp_im(pc_start - s->cs_base);
6904
            gen_helper_hlt(tcg_const_i32(s->pc - pc_start));
6905
            s->is_jmp = 3;
6906
        }
6907
        break;
6908
    case 0x100:
6909
        modrm = ldub_code(s->pc++);
6910
        mod = (modrm >> 6) & 3;
6911
        op = (modrm >> 3) & 7;
6912
        switch(op) {
6913
        case 0: /* sldt */
6914
            if (!s->pe || s->vm86)
6915
                goto illegal_op;
6916
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
6917
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,ldt.selector));
6918
            ot = OT_WORD;
6919
            if (mod == 3)
6920
                ot += s->dflag;
6921
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
6922
            break;
6923
        case 2: /* lldt */
6924
            if (!s->pe || s->vm86)
6925
                goto illegal_op;
6926
            if (s->cpl != 0) {
6927
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6928
            } else {
6929
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
6930
                gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
6931
                gen_jmp_im(pc_start - s->cs_base);
6932
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6933
                gen_helper_lldt(cpu_tmp2_i32);
6934
            }
6935
            break;
6936
        case 1: /* str */
6937
            if (!s->pe || s->vm86)
6938
                goto illegal_op;
6939
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
6940
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,tr.selector));
6941
            ot = OT_WORD;
6942
            if (mod == 3)
6943
                ot += s->dflag;
6944
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
6945
            break;
6946
        case 3: /* ltr */
6947
            if (!s->pe || s->vm86)
6948
                goto illegal_op;
6949
            if (s->cpl != 0) {
6950
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6951
            } else {
6952
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
6953
                gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
6954
                gen_jmp_im(pc_start - s->cs_base);
6955
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6956
                gen_helper_ltr(cpu_tmp2_i32);
6957
            }
6958
            break;
6959
        case 4: /* verr */
6960
        case 5: /* verw */
6961
            if (!s->pe || s->vm86)
6962
                goto illegal_op;
6963
            gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
6964
            if (s->cc_op != CC_OP_DYNAMIC)
6965
                gen_op_set_cc_op(s->cc_op);
6966
            if (op == 4)
6967
                gen_helper_verr(cpu_T[0]);
6968
            else
6969
                gen_helper_verw(cpu_T[0]);
6970
            s->cc_op = CC_OP_EFLAGS;
6971
            break;
6972
        default:
6973
            goto illegal_op;
6974
        }
6975
        break;
6976
    case 0x101:
6977
        modrm = ldub_code(s->pc++);
6978
        mod = (modrm >> 6) & 3;
6979
        op = (modrm >> 3) & 7;
6980
        rm = modrm & 7;
6981
        switch(op) {
6982
        case 0: /* sgdt */
6983
            if (mod == 3)
6984
                goto illegal_op;
6985
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ);
6986
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6987
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.limit));
6988
            gen_op_st_T0_A0(OT_WORD + s->mem_index);
6989
            gen_add_A0_im(s, 2);
6990
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.base));
6991
            if (!s->dflag)
6992
                gen_op_andl_T0_im(0xffffff);
6993
            gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
6994
            break;
6995
        case 1:
6996
            if (mod == 3) {
6997
                switch (rm) {
6998
                case 0: /* monitor */
6999
                    if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
7000
                        s->cpl != 0)
7001
                        goto illegal_op;
7002
                    if (s->cc_op != CC_OP_DYNAMIC)
7003
                        gen_op_set_cc_op(s->cc_op);
7004
                    gen_jmp_im(pc_start - s->cs_base);
7005
#ifdef TARGET_X86_64
7006
                    if (s->aflag == 2) {
7007
                        gen_op_movq_A0_reg(R_EAX);
7008
                    } else
7009
#endif
7010
                    {
7011
                        gen_op_movl_A0_reg(R_EAX);
7012
                        if (s->aflag == 0)
7013
                            gen_op_andl_A0_ffff();
7014
                    }
7015
                    gen_add_A0_ds_seg(s);
7016
                    gen_helper_monitor(cpu_A0);
7017
                    break;
7018
                case 1: /* mwait */
7019
                    if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
7020
                        s->cpl != 0)
7021
                        goto illegal_op;
7022
                    if (s->cc_op != CC_OP_DYNAMIC) {
7023
                        gen_op_set_cc_op(s->cc_op);
7024
                        s->cc_op = CC_OP_DYNAMIC;
7025
                    }
7026
                    gen_jmp_im(pc_start - s->cs_base);
7027
                    gen_helper_mwait(tcg_const_i32(s->pc - pc_start));
7028
                    gen_eob(s);
7029
                    break;
7030
                default:
7031
                    goto illegal_op;
7032
                }
7033
            } else { /* sidt */
7034
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ);
7035
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7036
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.limit));
7037
                gen_op_st_T0_A0(OT_WORD + s->mem_index);
7038
                gen_add_A0_im(s, 2);
7039
                tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.base));
7040
                if (!s->dflag)
7041
                    gen_op_andl_T0_im(0xffffff);
7042
                gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
7043
            }
7044
            break;
7045
        case 2: /* lgdt */
7046
        case 3: /* lidt */
7047
            if (mod == 3) {
7048
                if (s->cc_op != CC_OP_DYNAMIC)
7049
                    gen_op_set_cc_op(s->cc_op);
7050
                gen_jmp_im(pc_start - s->cs_base);
7051
                switch(rm) {
7052
                case 0: /* VMRUN */
7053
                    if (!(s->flags & HF_SVME_MASK) || !s->pe)
7054
                        goto illegal_op;
7055
                    if (s->cpl != 0) {
7056
                        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7057
                        break;
7058
                    } else {
7059
                        gen_helper_vmrun(tcg_const_i32(s->aflag),
7060
                                         tcg_const_i32(s->pc - pc_start));
7061
                        tcg_gen_exit_tb(0);
7062
                        s->is_jmp = 3;
7063
                    }
7064
                    break;
7065
                case 1: /* VMMCALL */
7066
                    if (!(s->flags & HF_SVME_MASK))
7067
                        goto illegal_op;
7068
                    gen_helper_vmmcall();
7069
                    break;
7070
                case 2: /* VMLOAD */
7071
                    if (!(s->flags & HF_SVME_MASK) || !s->pe)
7072
                        goto illegal_op;
7073
                    if (s->cpl != 0) {
7074
                        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7075
                        break;
7076
                    } else {
7077
                        gen_helper_vmload(tcg_const_i32(s->aflag));
7078
                    }
7079
                    break;
7080
                case 3: /* VMSAVE */
7081
                    if (!(s->flags & HF_SVME_MASK) || !s->pe)
7082
                        goto illegal_op;
7083
                    if (s->cpl != 0) {
7084
                        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7085
                        break;
7086
                    } else {
7087
                        gen_helper_vmsave(tcg_const_i32(s->aflag));
7088
                    }
7089
                    break;
7090
                case 4: /* STGI */
7091
                    if ((!(s->flags & HF_SVME_MASK) &&
7092
                         !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) || 
7093
                        !s->pe)
7094
                        goto illegal_op;
7095
                    if (s->cpl != 0) {
7096
                        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7097
                        break;
7098
                    } else {
7099
                        gen_helper_stgi();
7100
                    }
7101
                    break;
7102
                case 5: /* CLGI */
7103
                    if (!(s->flags & HF_SVME_MASK) || !s->pe)
7104
                        goto illegal_op;
7105
                    if (s->cpl != 0) {
7106
                        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7107
                        break;
7108
                    } else {
7109
                        gen_helper_clgi();
7110
                    }
7111
                    break;
7112
                case 6: /* SKINIT */
7113
                    if ((!(s->flags & HF_SVME_MASK) && 
7114
                         !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) || 
7115
                        !s->pe)
7116
                        goto illegal_op;
7117
                    gen_helper_skinit();
7118
                    break;
7119
                case 7: /* INVLPGA */
7120
                    if (!(s->flags & HF_SVME_MASK) || !s->pe)
7121
                        goto illegal_op;
7122
                    if (s->cpl != 0) {
7123
                        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7124
                        break;
7125
                    } else {
7126
                        gen_helper_invlpga(tcg_const_i32(s->aflag));
7127
                    }
7128
                    break;
7129
                default:
7130
                    goto illegal_op;
7131
                }
7132
            } else if (s->cpl != 0) {
7133
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7134
            } else {
7135
                gen_svm_check_intercept(s, pc_start,
7136
                                        op==2 ? SVM_EXIT_GDTR_WRITE : SVM_EXIT_IDTR_WRITE);
7137
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7138
                gen_op_ld_T1_A0(OT_WORD + s->mem_index);
7139
                gen_add_A0_im(s, 2);
7140
                gen_op_ld_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
7141
                if (!s->dflag)
7142
                    gen_op_andl_T0_im(0xffffff);
7143
                if (op == 2) {
7144
                    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,gdt.base));
7145
                    tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,gdt.limit));
7146
                } else {
7147
                    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,idt.base));
7148
                    tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,idt.limit));
7149
                }
7150
            }
7151
            break;
7152
        case 4: /* smsw */
7153
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
7154
#if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
7155
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]) + 4);
7156
#else
7157
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]));
7158
#endif
7159
            gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 1);
7160
            break;
7161
        case 6: /* lmsw */
7162
            if (s->cpl != 0) {
7163
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7164
            } else {
7165
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7166
                gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
7167
                gen_helper_lmsw(cpu_T[0]);
7168
                gen_jmp_im(s->pc - s->cs_base);
7169
                gen_eob(s);
7170
            }
7171
            break;
7172
        case 7: /* invlpg */
7173
            if (s->cpl != 0) {
7174
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7175
            } else {
7176
                if (mod == 3) {
7177
#ifdef TARGET_X86_64
7178
                    if (CODE64(s) && rm == 0) {
7179
                        /* swapgs */
7180
                        tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,segs[R_GS].base));
7181
                        tcg_gen_ld_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,kernelgsbase));
7182
                        tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,segs[R_GS].base));
7183
                        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,kernelgsbase));
7184
                    } else
7185
#endif
7186
                    {
7187
                        goto illegal_op;
7188
                    }
7189
                } else {
7190
                    if (s->cc_op != CC_OP_DYNAMIC)
7191
                        gen_op_set_cc_op(s->cc_op);
7192
                    gen_jmp_im(pc_start - s->cs_base);
7193
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7194
                    gen_helper_invlpg(cpu_A0);
7195
                    gen_jmp_im(s->pc - s->cs_base);
7196
                    gen_eob(s);
7197
                }
7198
            }
7199
            break;
7200
        default:
7201
            goto illegal_op;
7202
        }
7203
        break;
7204
    case 0x108: /* invd */
7205
    case 0x109: /* wbinvd */
7206
        if (s->cpl != 0) {
7207
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7208
        } else {
7209
            gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
7210
            /* nothing to do */
7211
        }
7212
        break;
7213
    case 0x63: /* arpl or movslS (x86_64) */
7214
#ifdef TARGET_X86_64
7215
        if (CODE64(s)) {
7216
            int d_ot;
7217
            /* d_ot is the size of destination */
7218
            d_ot = dflag + OT_WORD;
7219

    
7220
            modrm = ldub_code(s->pc++);
7221
            reg = ((modrm >> 3) & 7) | rex_r;
7222
            mod = (modrm >> 6) & 3;
7223
            rm = (modrm & 7) | REX_B(s);
7224

    
7225
            if (mod == 3) {
7226
                gen_op_mov_TN_reg(OT_LONG, 0, rm);
7227
                /* sign extend */
7228
                if (d_ot == OT_QUAD)
7229
                    tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
7230
                gen_op_mov_reg_T0(d_ot, reg);
7231
            } else {
7232
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7233
                if (d_ot == OT_QUAD) {
7234
                    gen_op_lds_T0_A0(OT_LONG + s->mem_index);
7235
                } else {
7236
                    gen_op_ld_T0_A0(OT_LONG + s->mem_index);
7237
                }
7238
                gen_op_mov_reg_T0(d_ot, reg);
7239
            }
7240
        } else
7241
#endif
7242
        {
7243
            int label1;
7244
            TCGv t0, t1, t2;
7245

    
7246
            if (!s->pe || s->vm86)
7247
                goto illegal_op;
7248
            t0 = tcg_temp_local_new();
7249
            t1 = tcg_temp_local_new();
7250
            t2 = tcg_temp_local_new();
7251
            ot = OT_WORD;
7252
            modrm = ldub_code(s->pc++);
7253
            reg = (modrm >> 3) & 7;
7254
            mod = (modrm >> 6) & 3;
7255
            rm = modrm & 7;
7256
            if (mod != 3) {
7257
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7258
                gen_op_ld_v(ot + s->mem_index, t0, cpu_A0);
7259
            } else {
7260
                gen_op_mov_v_reg(ot, t0, rm);
7261
            }
7262
            gen_op_mov_v_reg(ot, t1, reg);
7263
            tcg_gen_andi_tl(cpu_tmp0, t0, 3);
7264
            tcg_gen_andi_tl(t1, t1, 3);
7265
            tcg_gen_movi_tl(t2, 0);
7266
            label1 = gen_new_label();
7267
            tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, t1, label1);
7268
            tcg_gen_andi_tl(t0, t0, ~3);
7269
            tcg_gen_or_tl(t0, t0, t1);
7270
            tcg_gen_movi_tl(t2, CC_Z);
7271
            gen_set_label(label1);
7272
            if (mod != 3) {
7273
                gen_op_st_v(ot + s->mem_index, t0, cpu_A0);
7274
            } else {
7275
                gen_op_mov_reg_v(ot, rm, t0);
7276
            }
7277
            if (s->cc_op != CC_OP_DYNAMIC)
7278
                gen_op_set_cc_op(s->cc_op);
7279
            gen_compute_eflags(cpu_cc_src);
7280
            tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
7281
            tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
7282
            s->cc_op = CC_OP_EFLAGS;
7283
            tcg_temp_free(t0);
7284
            tcg_temp_free(t1);
7285
            tcg_temp_free(t2);
7286
        }
7287
        break;
7288
    case 0x102: /* lar */
7289
    case 0x103: /* lsl */
7290
        {
7291
            int label1;
7292
            TCGv t0;
7293
            if (!s->pe || s->vm86)
7294
                goto illegal_op;
7295
            ot = dflag ? OT_LONG : OT_WORD;
7296
            modrm = ldub_code(s->pc++);
7297
            reg = ((modrm >> 3) & 7) | rex_r;
7298
            gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
7299
            t0 = tcg_temp_local_new();
7300
            if (s->cc_op != CC_OP_DYNAMIC)
7301
                gen_op_set_cc_op(s->cc_op);
7302
            if (b == 0x102)
7303
                gen_helper_lar(t0, cpu_T[0]);
7304
            else
7305
                gen_helper_lsl(t0, cpu_T[0]);
7306
            tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
7307
            label1 = gen_new_label();
7308
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
7309
            gen_op_mov_reg_v(ot, reg, t0);
7310
            gen_set_label(label1);
7311
            s->cc_op = CC_OP_EFLAGS;
7312
            tcg_temp_free(t0);
7313
        }
7314
        break;
7315
    case 0x118:
7316
        modrm = ldub_code(s->pc++);
7317
        mod = (modrm >> 6) & 3;
7318
        op = (modrm >> 3) & 7;
7319
        switch(op) {
7320
        case 0: /* prefetchnta */
7321
        case 1: /* prefetchnt0 */
7322
        case 2: /* prefetchnt0 */
7323
        case 3: /* prefetchnt0 */
7324
            if (mod == 3)
7325
                goto illegal_op;
7326
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7327
            /* nothing more to do */
7328
            break;
7329
        default: /* nop (multi byte) */
7330
            gen_nop_modrm(s, modrm);
7331
            break;
7332
        }
7333
        break;
7334
    case 0x119 ... 0x11f: /* nop (multi byte) */
7335
        modrm = ldub_code(s->pc++);
7336
        gen_nop_modrm(s, modrm);
7337
        break;
7338
    case 0x120: /* mov reg, crN */
7339
    case 0x122: /* mov crN, reg */
7340
        if (s->cpl != 0) {
7341
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7342
        } else {
7343
            modrm = ldub_code(s->pc++);
7344
            if ((modrm & 0xc0) != 0xc0)
7345
                goto illegal_op;
7346
            rm = (modrm & 7) | REX_B(s);
7347
            reg = ((modrm >> 3) & 7) | rex_r;
7348
            if (CODE64(s))
7349
                ot = OT_QUAD;
7350
            else
7351
                ot = OT_LONG;
7352
            switch(reg) {
7353
            case 0:
7354
            case 2:
7355
            case 3:
7356
            case 4:
7357
            case 8:
7358
                if (s->cc_op != CC_OP_DYNAMIC)
7359
                    gen_op_set_cc_op(s->cc_op);
7360
                gen_jmp_im(pc_start - s->cs_base);
7361
                if (b & 2) {
7362
                    gen_op_mov_TN_reg(ot, 0, rm);
7363
                    gen_helper_write_crN(tcg_const_i32(reg), cpu_T[0]);
7364
                    gen_jmp_im(s->pc - s->cs_base);
7365
                    gen_eob(s);
7366
                } else {
7367
                    gen_helper_read_crN(cpu_T[0], tcg_const_i32(reg));
7368
                    gen_op_mov_reg_T0(ot, rm);
7369
                }
7370
                break;
7371
            default:
7372
                goto illegal_op;
7373
            }
7374
        }
7375
        break;
7376
    case 0x121: /* mov reg, drN */
7377
    case 0x123: /* mov drN, reg */
7378
        if (s->cpl != 0) {
7379
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7380
        } else {
7381
            modrm = ldub_code(s->pc++);
7382
            if ((modrm & 0xc0) != 0xc0)
7383
                goto illegal_op;
7384
            rm = (modrm & 7) | REX_B(s);
7385
            reg = ((modrm >> 3) & 7) | rex_r;
7386
            if (CODE64(s))
7387
                ot = OT_QUAD;
7388
            else
7389
                ot = OT_LONG;
7390
            /* XXX: do it dynamically with CR4.DE bit */
7391
            if (reg == 4 || reg == 5 || reg >= 8)
7392
                goto illegal_op;
7393
            if (b & 2) {
7394
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
7395
                gen_op_mov_TN_reg(ot, 0, rm);
7396
                gen_helper_movl_drN_T0(tcg_const_i32(reg), cpu_T[0]);
7397
                gen_jmp_im(s->pc - s->cs_base);
7398
                gen_eob(s);
7399
            } else {
7400
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
7401
                tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,dr[reg]));
7402
                gen_op_mov_reg_T0(ot, rm);
7403
            }
7404
        }
7405
        break;
7406
    case 0x106: /* clts */
7407
        if (s->cpl != 0) {
7408
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7409
        } else {
7410
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7411
            gen_helper_clts();
7412
            /* abort block because static cpu state changed */
7413
            gen_jmp_im(s->pc - s->cs_base);
7414
            gen_eob(s);
7415
        }
7416
        break;
7417
    /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7418
    case 0x1c3: /* MOVNTI reg, mem */
7419
        if (!(s->cpuid_features & CPUID_SSE2))
7420
            goto illegal_op;
7421
        ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
7422
        modrm = ldub_code(s->pc++);
7423
        mod = (modrm >> 6) & 3;
7424
        if (mod == 3)
7425
            goto illegal_op;
7426
        reg = ((modrm >> 3) & 7) | rex_r;
7427
        /* generate a generic store */
7428
        gen_ldst_modrm(s, modrm, ot, reg, 1);
7429
        break;
7430
    case 0x1ae:
7431
        modrm = ldub_code(s->pc++);
7432
        mod = (modrm >> 6) & 3;
7433
        op = (modrm >> 3) & 7;
7434
        switch(op) {
7435
        case 0: /* fxsave */
7436
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
7437
                (s->flags & HF_EM_MASK))
7438
                goto illegal_op;
7439
            if (s->flags & HF_TS_MASK) {
7440
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7441
                break;
7442
            }
7443
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7444
            if (s->cc_op != CC_OP_DYNAMIC)
7445
                gen_op_set_cc_op(s->cc_op);
7446
            gen_jmp_im(pc_start - s->cs_base);
7447
            gen_helper_fxsave(cpu_A0, tcg_const_i32((s->dflag == 2)));
7448
            break;
7449
        case 1: /* fxrstor */
7450
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
7451
                (s->flags & HF_EM_MASK))
7452
                goto illegal_op;
7453
            if (s->flags & HF_TS_MASK) {
7454
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7455
                break;
7456
            }
7457
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7458
            if (s->cc_op != CC_OP_DYNAMIC)
7459
                gen_op_set_cc_op(s->cc_op);
7460
            gen_jmp_im(pc_start - s->cs_base);
7461
            gen_helper_fxrstor(cpu_A0, tcg_const_i32((s->dflag == 2)));
7462
            break;
7463
        case 2: /* ldmxcsr */
7464
        case 3: /* stmxcsr */
7465
            if (s->flags & HF_TS_MASK) {
7466
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7467
                break;
7468
            }
7469
            if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
7470
                mod == 3)
7471
                goto illegal_op;
7472
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7473
            if (op == 2) {
7474
                gen_op_ld_T0_A0(OT_LONG + s->mem_index);
7475
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
7476
            } else {
7477
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
7478
                gen_op_st_T0_A0(OT_LONG + s->mem_index);
7479
            }
7480
            break;
7481
        case 5: /* lfence */
7482
        case 6: /* mfence */
7483
            if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE))
7484
                goto illegal_op;
7485
            break;
7486
        case 7: /* sfence / clflush */
7487
            if ((modrm & 0xc7) == 0xc0) {
7488
                /* sfence */
7489
                /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
7490
                if (!(s->cpuid_features & CPUID_SSE))
7491
                    goto illegal_op;
7492
            } else {
7493
                /* clflush */
7494
                if (!(s->cpuid_features & CPUID_CLFLUSH))
7495
                    goto illegal_op;
7496
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7497
            }
7498
            break;
7499
        default:
7500
            goto illegal_op;
7501
        }
7502
        break;
7503
    case 0x10d: /* 3DNow! prefetch(w) */
7504
        modrm = ldub_code(s->pc++);
7505
        mod = (modrm >> 6) & 3;
7506
        if (mod == 3)
7507
            goto illegal_op;
7508
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7509
        /* ignore for now */
7510
        break;
7511
    case 0x1aa: /* rsm */
7512
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
7513
        if (!(s->flags & HF_SMM_MASK))
7514
            goto illegal_op;
7515
        if (s->cc_op != CC_OP_DYNAMIC) {
7516
            gen_op_set_cc_op(s->cc_op);
7517
            s->cc_op = CC_OP_DYNAMIC;
7518
        }
7519
        gen_jmp_im(s->pc - s->cs_base);
7520
        gen_helper_rsm();
7521
        gen_eob(s);
7522
        break;
7523
    case 0x1b8: /* SSE4.2 popcnt */
7524
        if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
7525
             PREFIX_REPZ)
7526
            goto illegal_op;
7527
        if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
7528
            goto illegal_op;
7529

    
7530
        modrm = ldub_code(s->pc++);
7531
        reg = ((modrm >> 3) & 7);
7532

    
7533
        if (s->prefix & PREFIX_DATA)
7534
            ot = OT_WORD;
7535
        else if (s->dflag != 2)
7536
            ot = OT_LONG;
7537
        else
7538
            ot = OT_QUAD;
7539

    
7540
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
7541
        gen_helper_popcnt(cpu_T[0], cpu_T[0], tcg_const_i32(ot));
7542
        gen_op_mov_reg_T0(ot, reg);
7543

    
7544
        s->cc_op = CC_OP_EFLAGS;
7545
        break;
7546
    case 0x10e ... 0x10f:
7547
        /* 3DNow! instructions, ignore prefixes */
7548
        s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
7549
    case 0x110 ... 0x117:
7550
    case 0x128 ... 0x12f:
7551
    case 0x138 ... 0x13a:
7552
    case 0x150 ... 0x177:
7553
    case 0x17c ... 0x17f:
7554
    case 0x1c2:
7555
    case 0x1c4 ... 0x1c6:
7556
    case 0x1d0 ... 0x1fe:
7557
        gen_sse(s, b, pc_start, rex_r);
7558
        break;
7559
    default:
7560
        goto illegal_op;
7561
    }
7562
    /* lock generation */
7563
    if (s->prefix & PREFIX_LOCK)
7564
        gen_helper_unlock();
7565
    return s->pc;
7566
 illegal_op:
7567
    if (s->prefix & PREFIX_LOCK)
7568
        gen_helper_unlock();
7569
    /* XXX: ensure that no lock was generated */
7570
    gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
7571
    return s->pc;
7572
}
7573

    
7574
void optimize_flags_init(void)
7575
{
7576
#if TCG_TARGET_REG_BITS == 32
7577
    assert(sizeof(CCTable) == (1 << 3));
7578
#else
7579
    assert(sizeof(CCTable) == (1 << 4));
7580
#endif
7581
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
7582
    cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0,
7583
                                       offsetof(CPUState, cc_op), "cc_op");
7584
    cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_src),
7585
                                    "cc_src");
7586
    cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_dst),
7587
                                    "cc_dst");
7588
    cpu_cc_tmp = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_tmp),
7589
                                    "cc_tmp");
7590

    
7591
    /* register helpers */
7592
#define GEN_HELPER 2
7593
#include "helper.h"
7594
}
7595

    
7596
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
7597
   basic block 'tb'. If search_pc is TRUE, also generate PC
7598
   information for each intermediate instruction. */
7599
static inline void gen_intermediate_code_internal(CPUState *env,
7600
                                                  TranslationBlock *tb,
7601
                                                  int search_pc)
7602
{
7603
    DisasContext dc1, *dc = &dc1;
7604
    target_ulong pc_ptr;
7605
    uint16_t *gen_opc_end;
7606
    CPUBreakpoint *bp;
7607
    int j, lj, cflags;
7608
    uint64_t flags;
7609
    target_ulong pc_start;
7610
    target_ulong cs_base;
7611
    int num_insns;
7612
    int max_insns;
7613

    
7614
    /* generate intermediate code */
7615
    pc_start = tb->pc;
7616
    cs_base = tb->cs_base;
7617
    flags = tb->flags;
7618
    cflags = tb->cflags;
7619

    
7620
    dc->pe = (flags >> HF_PE_SHIFT) & 1;
7621
    dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
7622
    dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
7623
    dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
7624
    dc->f_st = 0;
7625
    dc->vm86 = (flags >> VM_SHIFT) & 1;
7626
    dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
7627
    dc->iopl = (flags >> IOPL_SHIFT) & 3;
7628
    dc->tf = (flags >> TF_SHIFT) & 1;
7629
    dc->singlestep_enabled = env->singlestep_enabled;
7630
    dc->cc_op = CC_OP_DYNAMIC;
7631
    dc->cs_base = cs_base;
7632
    dc->tb = tb;
7633
    dc->popl_esp_hack = 0;
7634
    /* select memory access functions */
7635
    dc->mem_index = 0;
7636
    if (flags & HF_SOFTMMU_MASK) {
7637
        if (dc->cpl == 3)
7638
            dc->mem_index = 2 * 4;
7639
        else
7640
            dc->mem_index = 1 * 4;
7641
    }
7642
    dc->cpuid_features = env->cpuid_features;
7643
    dc->cpuid_ext_features = env->cpuid_ext_features;
7644
    dc->cpuid_ext2_features = env->cpuid_ext2_features;
7645
    dc->cpuid_ext3_features = env->cpuid_ext3_features;
7646
#ifdef TARGET_X86_64
7647
    dc->lma = (flags >> HF_LMA_SHIFT) & 1;
7648
    dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
7649
#endif
7650
    dc->flags = flags;
7651
    dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
7652
                    (flags & HF_INHIBIT_IRQ_MASK)
7653
#ifndef CONFIG_SOFTMMU
7654
                    || (flags & HF_SOFTMMU_MASK)
7655
#endif
7656
                    );
7657
#if 0
7658
    /* check addseg logic */
7659
    if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
7660
        printf("ERROR addseg\n");
7661
#endif
7662

    
7663
    cpu_T[0] = tcg_temp_new();
7664
    cpu_T[1] = tcg_temp_new();
7665
    cpu_A0 = tcg_temp_new();
7666
    cpu_T3 = tcg_temp_new();
7667

    
7668
    cpu_tmp0 = tcg_temp_new();
7669
    cpu_tmp1_i64 = tcg_temp_new_i64();
7670
    cpu_tmp2_i32 = tcg_temp_new_i32();
7671
    cpu_tmp3_i32 = tcg_temp_new_i32();
7672
    cpu_tmp4 = tcg_temp_new();
7673
    cpu_tmp5 = tcg_temp_new();
7674
    cpu_tmp6 = tcg_temp_new();
7675
    cpu_ptr0 = tcg_temp_new_ptr();
7676
    cpu_ptr1 = tcg_temp_new_ptr();
7677

    
7678
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
7679

    
7680
    dc->is_jmp = DISAS_NEXT;
7681
    pc_ptr = pc_start;
7682
    lj = -1;
7683
    num_insns = 0;
7684
    max_insns = tb->cflags & CF_COUNT_MASK;
7685
    if (max_insns == 0)
7686
        max_insns = CF_COUNT_MASK;
7687

    
7688
    gen_icount_start();
7689
    for(;;) {
7690
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
7691
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
7692
                if (bp->pc == pc_ptr &&
7693
                    !((bp->flags & BP_CPU) && (tb->flags & HF_RF_MASK))) {
7694
                    gen_debug(dc, pc_ptr - dc->cs_base);
7695
                    break;
7696
                }
7697
            }
7698
        }
7699
        if (search_pc) {
7700
            j = gen_opc_ptr - gen_opc_buf;
7701
            if (lj < j) {
7702
                lj++;
7703
                while (lj < j)
7704
                    gen_opc_instr_start[lj++] = 0;
7705
            }
7706
            gen_opc_pc[lj] = pc_ptr;
7707
            gen_opc_cc_op[lj] = dc->cc_op;
7708
            gen_opc_instr_start[lj] = 1;
7709
            gen_opc_icount[lj] = num_insns;
7710
        }
7711
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
7712
            gen_io_start();
7713

    
7714
        pc_ptr = disas_insn(dc, pc_ptr);
7715
        num_insns++;
7716
        /* stop translation if indicated */
7717
        if (dc->is_jmp)
7718
            break;
7719
        /* if single step mode, we generate only one instruction and
7720
           generate an exception */
7721
        /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
7722
           the flag and abort the translation to give the irqs a
7723
           change to be happen */
7724
        if (dc->tf || dc->singlestep_enabled ||
7725
            (flags & HF_INHIBIT_IRQ_MASK)) {
7726
            gen_jmp_im(pc_ptr - dc->cs_base);
7727
            gen_eob(dc);
7728
            break;
7729
        }
7730
        /* if too long translation, stop generation too */
7731
        if (gen_opc_ptr >= gen_opc_end ||
7732
            (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32) ||
7733
            num_insns >= max_insns) {
7734
            gen_jmp_im(pc_ptr - dc->cs_base);
7735
            gen_eob(dc);
7736
            break;
7737
        }
7738
        if (singlestep) {
7739
            gen_jmp_im(pc_ptr - dc->cs_base);
7740
            gen_eob(dc);
7741
            break;
7742
        }
7743
    }
7744
    if (tb->cflags & CF_LAST_IO)
7745
        gen_io_end();
7746
    gen_icount_end(tb, num_insns);
7747
    *gen_opc_ptr = INDEX_op_end;
7748
    /* we don't forget to fill the last values */
7749
    if (search_pc) {
7750
        j = gen_opc_ptr - gen_opc_buf;
7751
        lj++;
7752
        while (lj <= j)
7753
            gen_opc_instr_start[lj++] = 0;
7754
    }
7755

    
7756
#ifdef DEBUG_DISAS
7757
    log_cpu_state_mask(CPU_LOG_TB_CPU, env, X86_DUMP_CCOP);
7758
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
7759
        int disas_flags;
7760
        qemu_log("----------------\n");
7761
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
7762
#ifdef TARGET_X86_64
7763
        if (dc->code64)
7764
            disas_flags = 2;
7765
        else
7766
#endif
7767
            disas_flags = !dc->code32;
7768
        log_target_disas(pc_start, pc_ptr - pc_start, disas_flags);
7769
        qemu_log("\n");
7770
    }
7771
#endif
7772

    
7773
    if (!search_pc) {
7774
        tb->size = pc_ptr - pc_start;
7775
        tb->icount = num_insns;
7776
    }
7777
}
7778

    
7779
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
7780
{
7781
    gen_intermediate_code_internal(env, tb, 0);
7782
}
7783

    
7784
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
7785
{
7786
    gen_intermediate_code_internal(env, tb, 1);
7787
}
7788

    
7789
void gen_pc_load(CPUState *env, TranslationBlock *tb,
7790
                unsigned long searched_pc, int pc_pos, void *puc)
7791
{
7792
    int cc_op;
7793
#ifdef DEBUG_DISAS
7794
    if (qemu_loglevel_mask(CPU_LOG_TB_OP)) {
7795
        int i;
7796
        qemu_log("RESTORE:\n");
7797
        for(i = 0;i <= pc_pos; i++) {
7798
            if (gen_opc_instr_start[i]) {
7799
                qemu_log("0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]);
7800
            }
7801
        }
7802
        qemu_log("spc=0x%08lx pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
7803
                searched_pc, pc_pos, gen_opc_pc[pc_pos] - tb->cs_base,
7804
                (uint32_t)tb->cs_base);
7805
    }
7806
#endif
7807
    env->eip = gen_opc_pc[pc_pos] - tb->cs_base;
7808
    cc_op = gen_opc_cc_op[pc_pos];
7809
    if (cc_op != CC_OP_DYNAMIC)
7810
        env->cc_op = cc_op;
7811
}