Statistics
| Branch: | Revision:

root / target-i386 / translate.c @ 93fcfe39

History | View | Annotate | Download (249.4 kB)

1
/*
2
 *  i386 translation
3
 *
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
19
 */
20
#include <stdarg.h>
21
#include <stdlib.h>
22
#include <stdio.h>
23
#include <string.h>
24
#include <inttypes.h>
25
#include <signal.h>
26
#include <assert.h>
27

    
28
#include "cpu.h"
29
#include "exec-all.h"
30
#include "disas.h"
31
#include "tcg-op.h"
32

    
33
#include "helper.h"
34
#define GEN_HELPER 1
35
#include "helper.h"
36

    
37
#define PREFIX_REPZ   0x01
38
#define PREFIX_REPNZ  0x02
39
#define PREFIX_LOCK   0x04
40
#define PREFIX_DATA   0x08
41
#define PREFIX_ADR    0x10
42

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

    
61
//#define MACRO_TEST   1
62

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

    
76
#include "gen-icount.h"
77

    
78
#ifdef TARGET_X86_64
79
static int x86_64_hregs;
80
#endif
81

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
250
#ifdef TARGET_X86_64
251

    
252
#define NB_OP_SIZES 4
253

    
254
#else /* !TARGET_X86_64 */
255

    
256
#define NB_OP_SIZES 3
257

    
258
#endif /* !TARGET_X86_64 */
259

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
608
static inline void gen_string_movl_A0_ESI(DisasContext *s)
609
{
610
    int override;
611

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

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

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

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

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

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

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

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

    
726
}
727

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

    
736
}
737

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
911
    case CC_OP_LOGICB:
912
    case CC_OP_LOGICW:
913
    case CC_OP_LOGICL:
914
    case CC_OP_LOGICQ:
915

    
916
    case CC_OP_INCB:
917
    case CC_OP_INCW:
918
    case CC_OP_INCL:
919
    case CC_OP_INCQ:
920

    
921
    case CC_OP_DECB:
922
    case CC_OP_DECW:
923
    case CC_OP_DECL:
924
    case CC_OP_DECQ:
925

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

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

    
947
    inv = b & 1;
948
    jcc_op = (b >> 1) & 7;
949

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1431
    if (ot == OT_QUAD)
1432
        mask = 0x3f;
1433
    else
1434
        mask = 0x1f;
1435

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

    
1442
    tcg_gen_andi_tl(cpu_T[1], cpu_T[1], mask);
1443

    
1444
    tcg_gen_addi_tl(cpu_tmp5, cpu_T[1], -1);
1445

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

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

    
1471
    /* XXX: inefficient */
1472
    t0 = tcg_temp_local_new();
1473
    t1 = tcg_temp_local_new();
1474

    
1475
    tcg_gen_mov_tl(t0, cpu_T[0]);
1476
    tcg_gen_mov_tl(t1, cpu_T3);
1477

    
1478
    shift_label = gen_new_label();
1479
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, shift_label);
1480

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

    
1491
    tcg_temp_free(t0);
1492
    tcg_temp_free(t1);
1493
}
1494

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

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

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

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

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

    
1554
/* XXX: add faster immediate case */
1555
static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, 
1556
                          int is_right)
1557
{
1558
    target_ulong mask;
1559
    int label1, label2, data_bits;
1560
    TCGv t0, t1, t2, a0;
1561

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

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

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

    
1581
    tcg_gen_mov_tl(t1, cpu_T[1]);
1582

    
1583
    tcg_gen_andi_tl(t1, t1, mask);
1584

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

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

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

    
1624
    label2 = gen_new_label();
1625
    tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label2);
1626

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

    
1645
    tcg_temp_free(t0);
1646
    tcg_temp_free(t1);
1647
    tcg_temp_free(t2);
1648
    tcg_temp_free(a0);
1649
}
1650

    
1651
/* XXX: add faster immediate = 1 case */
1652
static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, 
1653
                           int is_right)
1654
{
1655
    int label1;
1656

    
1657
    if (s->cc_op != CC_OP_DYNAMIC)
1658
        gen_op_set_cc_op(s->cc_op);
1659

    
1660
    /* load */
1661
    if (op1 == OR_TMP0)
1662
        gen_op_ld_T0_A0(ot + s->mem_index);
1663
    else
1664
        gen_op_mov_TN_reg(ot, 0, op1);
1665
    
1666
    if (is_right) {
1667
        switch (ot) {
1668
        case 0: gen_helper_rcrb(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1669
        case 1: gen_helper_rcrw(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1670
        case 2: gen_helper_rcrl(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1671
#ifdef TARGET_X86_64
1672
        case 3: gen_helper_rcrq(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1673
#endif
1674
        }
1675
    } else {
1676
        switch (ot) {
1677
        case 0: gen_helper_rclb(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1678
        case 1: gen_helper_rclw(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1679
        case 2: gen_helper_rcll(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1680
#ifdef TARGET_X86_64
1681
        case 3: gen_helper_rclq(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1682
#endif
1683
        }
1684
    }
1685
    /* store */
1686
    if (op1 == OR_TMP0)
1687
        gen_op_st_T0_A0(ot + s->mem_index);
1688
    else
1689
        gen_op_mov_reg_T0(ot, op1);
1690

    
1691
    /* update eflags */
1692
    label1 = gen_new_label();
1693
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cc_tmp, -1, label1);
1694

    
1695
    tcg_gen_mov_tl(cpu_cc_src, cpu_cc_tmp);
1696
    tcg_gen_discard_tl(cpu_cc_dst);
1697
    tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
1698
        
1699
    gen_set_label(label1);
1700
    s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1701
}
1702

    
1703
/* XXX: add faster immediate case */
1704
static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1, 
1705
                                int is_right)
1706
{
1707
    int label1, label2, data_bits;
1708
    target_ulong mask;
1709
    TCGv t0, t1, t2, a0;
1710

    
1711
    t0 = tcg_temp_local_new();
1712
    t1 = tcg_temp_local_new();
1713
    t2 = tcg_temp_local_new();
1714
    a0 = tcg_temp_local_new();
1715

    
1716
    if (ot == OT_QUAD)
1717
        mask = 0x3f;
1718
    else
1719
        mask = 0x1f;
1720

    
1721
    /* load */
1722
    if (op1 == OR_TMP0) {
1723
        tcg_gen_mov_tl(a0, cpu_A0);
1724
        gen_op_ld_v(ot + s->mem_index, t0, a0);
1725
    } else {
1726
        gen_op_mov_v_reg(ot, t0, op1);
1727
    }
1728

    
1729
    tcg_gen_andi_tl(cpu_T3, cpu_T3, mask);
1730

    
1731
    tcg_gen_mov_tl(t1, cpu_T[1]);
1732
    tcg_gen_mov_tl(t2, cpu_T3);
1733

    
1734
    /* Must test zero case to avoid using undefined behaviour in TCG
1735
       shifts. */
1736
    label1 = gen_new_label();
1737
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
1738
    
1739
    tcg_gen_addi_tl(cpu_tmp5, t2, -1);
1740
    if (ot == OT_WORD) {
1741
        /* Note: we implement the Intel behaviour for shift count > 16 */
1742
        if (is_right) {
1743
            tcg_gen_andi_tl(t0, t0, 0xffff);
1744
            tcg_gen_shli_tl(cpu_tmp0, t1, 16);
1745
            tcg_gen_or_tl(t0, t0, cpu_tmp0);
1746
            tcg_gen_ext32u_tl(t0, t0);
1747

    
1748
            tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
1749
            
1750
            /* only needed if count > 16, but a test would complicate */
1751
            tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(32), t2);
1752
            tcg_gen_shl_tl(cpu_tmp0, t0, cpu_tmp5);
1753

    
1754
            tcg_gen_shr_tl(t0, t0, t2);
1755

    
1756
            tcg_gen_or_tl(t0, t0, cpu_tmp0);
1757
        } else {
1758
            /* XXX: not optimal */
1759
            tcg_gen_andi_tl(t0, t0, 0xffff);
1760
            tcg_gen_shli_tl(t1, t1, 16);
1761
            tcg_gen_or_tl(t1, t1, t0);
1762
            tcg_gen_ext32u_tl(t1, t1);
1763
            
1764
            tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
1765
            tcg_gen_sub_tl(cpu_tmp0, tcg_const_tl(32), cpu_tmp5);
1766
            tcg_gen_shr_tl(cpu_tmp6, t1, cpu_tmp0);
1767
            tcg_gen_or_tl(cpu_tmp4, cpu_tmp4, cpu_tmp6);
1768

    
1769
            tcg_gen_shl_tl(t0, t0, t2);
1770
            tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(32), t2);
1771
            tcg_gen_shr_tl(t1, t1, cpu_tmp5);
1772
            tcg_gen_or_tl(t0, t0, t1);
1773
        }
1774
    } else {
1775
        data_bits = 8 << ot;
1776
        if (is_right) {
1777
            if (ot == OT_LONG)
1778
                tcg_gen_ext32u_tl(t0, t0);
1779

    
1780
            tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
1781

    
1782
            tcg_gen_shr_tl(t0, t0, t2);
1783
            tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(data_bits), t2);
1784
            tcg_gen_shl_tl(t1, t1, cpu_tmp5);
1785
            tcg_gen_or_tl(t0, t0, t1);
1786
            
1787
        } else {
1788
            if (ot == OT_LONG)
1789
                tcg_gen_ext32u_tl(t1, t1);
1790

    
1791
            tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
1792
            
1793
            tcg_gen_shl_tl(t0, t0, t2);
1794
            tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(data_bits), t2);
1795
            tcg_gen_shr_tl(t1, t1, cpu_tmp5);
1796
            tcg_gen_or_tl(t0, t0, t1);
1797
        }
1798
    }
1799
    tcg_gen_mov_tl(t1, cpu_tmp4);
1800

    
1801
    gen_set_label(label1);
1802
    /* store */
1803
    if (op1 == OR_TMP0) {
1804
        gen_op_st_v(ot + s->mem_index, t0, a0);
1805
    } else {
1806
        gen_op_mov_reg_v(ot, op1, t0);
1807
    }
1808
    
1809
    /* update eflags */
1810
    if (s->cc_op != CC_OP_DYNAMIC)
1811
        gen_op_set_cc_op(s->cc_op);
1812

    
1813
    label2 = gen_new_label();
1814
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label2);
1815

    
1816
    tcg_gen_mov_tl(cpu_cc_src, t1);
1817
    tcg_gen_mov_tl(cpu_cc_dst, t0);
1818
    if (is_right) {
1819
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
1820
    } else {
1821
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
1822
    }
1823
    gen_set_label(label2);
1824
    s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1825

    
1826
    tcg_temp_free(t0);
1827
    tcg_temp_free(t1);
1828
    tcg_temp_free(t2);
1829
    tcg_temp_free(a0);
1830
}
1831

    
1832
static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
1833
{
1834
    if (s != OR_TMP1)
1835
        gen_op_mov_TN_reg(ot, 1, s);
1836
    switch(op) {
1837
    case OP_ROL:
1838
        gen_rot_rm_T1(s1, ot, d, 0);
1839
        break;
1840
    case OP_ROR:
1841
        gen_rot_rm_T1(s1, ot, d, 1);
1842
        break;
1843
    case OP_SHL:
1844
    case OP_SHL1:
1845
        gen_shift_rm_T1(s1, ot, d, 0, 0);
1846
        break;
1847
    case OP_SHR:
1848
        gen_shift_rm_T1(s1, ot, d, 1, 0);
1849
        break;
1850
    case OP_SAR:
1851
        gen_shift_rm_T1(s1, ot, d, 1, 1);
1852
        break;
1853
    case OP_RCL:
1854
        gen_rotc_rm_T1(s1, ot, d, 0);
1855
        break;
1856
    case OP_RCR:
1857
        gen_rotc_rm_T1(s1, ot, d, 1);
1858
        break;
1859
    }
1860
}
1861

    
1862
static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
1863
{
1864
    switch(op) {
1865
    case OP_SHL:
1866
    case OP_SHL1:
1867
        gen_shift_rm_im(s1, ot, d, c, 0, 0);
1868
        break;
1869
    case OP_SHR:
1870
        gen_shift_rm_im(s1, ot, d, c, 1, 0);
1871
        break;
1872
    case OP_SAR:
1873
        gen_shift_rm_im(s1, ot, d, c, 1, 1);
1874
        break;
1875
    default:
1876
        /* currently not optimized */
1877
        gen_op_movl_T1_im(c);
1878
        gen_shift(s1, op, ot, d, OR_TMP1);
1879
        break;
1880
    }
1881
}
1882

    
1883
static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr)
1884
{
1885
    target_long disp;
1886
    int havesib;
1887
    int base;
1888
    int index;
1889
    int scale;
1890
    int opreg;
1891
    int mod, rm, code, override, must_add_seg;
1892

    
1893
    override = s->override;
1894
    must_add_seg = s->addseg;
1895
    if (override >= 0)
1896
        must_add_seg = 1;
1897
    mod = (modrm >> 6) & 3;
1898
    rm = modrm & 7;
1899

    
1900
    if (s->aflag) {
1901

    
1902
        havesib = 0;
1903
        base = rm;
1904
        index = 0;
1905
        scale = 0;
1906

    
1907
        if (base == 4) {
1908
            havesib = 1;
1909
            code = ldub_code(s->pc++);
1910
            scale = (code >> 6) & 3;
1911
            index = ((code >> 3) & 7) | REX_X(s);
1912
            base = (code & 7);
1913
        }
1914
        base |= REX_B(s);
1915

    
1916
        switch (mod) {
1917
        case 0:
1918
            if ((base & 7) == 5) {
1919
                base = -1;
1920
                disp = (int32_t)ldl_code(s->pc);
1921
                s->pc += 4;
1922
                if (CODE64(s) && !havesib) {
1923
                    disp += s->pc + s->rip_offset;
1924
                }
1925
            } else {
1926
                disp = 0;
1927
            }
1928
            break;
1929
        case 1:
1930
            disp = (int8_t)ldub_code(s->pc++);
1931
            break;
1932
        default:
1933
        case 2:
1934
            disp = ldl_code(s->pc);
1935
            s->pc += 4;
1936
            break;
1937
        }
1938

    
1939
        if (base >= 0) {
1940
            /* for correct popl handling with esp */
1941
            if (base == 4 && s->popl_esp_hack)
1942
                disp += s->popl_esp_hack;
1943
#ifdef TARGET_X86_64
1944
            if (s->aflag == 2) {
1945
                gen_op_movq_A0_reg(base);
1946
                if (disp != 0) {
1947
                    gen_op_addq_A0_im(disp);
1948
                }
1949
            } else
1950
#endif
1951
            {
1952
                gen_op_movl_A0_reg(base);
1953
                if (disp != 0)
1954
                    gen_op_addl_A0_im(disp);
1955
            }
1956
        } else {
1957
#ifdef TARGET_X86_64
1958
            if (s->aflag == 2) {
1959
                gen_op_movq_A0_im(disp);
1960
            } else
1961
#endif
1962
            {
1963
                gen_op_movl_A0_im(disp);
1964
            }
1965
        }
1966
        /* XXX: index == 4 is always invalid */
1967
        if (havesib && (index != 4 || scale != 0)) {
1968
#ifdef TARGET_X86_64
1969
            if (s->aflag == 2) {
1970
                gen_op_addq_A0_reg_sN(scale, index);
1971
            } else
1972
#endif
1973
            {
1974
                gen_op_addl_A0_reg_sN(scale, index);
1975
            }
1976
        }
1977
        if (must_add_seg) {
1978
            if (override < 0) {
1979
                if (base == R_EBP || base == R_ESP)
1980
                    override = R_SS;
1981
                else
1982
                    override = R_DS;
1983
            }
1984
#ifdef TARGET_X86_64
1985
            if (s->aflag == 2) {
1986
                gen_op_addq_A0_seg(override);
1987
            } else
1988
#endif
1989
            {
1990
                gen_op_addl_A0_seg(override);
1991
            }
1992
        }
1993
    } else {
1994
        switch (mod) {
1995
        case 0:
1996
            if (rm == 6) {
1997
                disp = lduw_code(s->pc);
1998
                s->pc += 2;
1999
                gen_op_movl_A0_im(disp);
2000
                rm = 0; /* avoid SS override */
2001
                goto no_rm;
2002
            } else {
2003
                disp = 0;
2004
            }
2005
            break;
2006
        case 1:
2007
            disp = (int8_t)ldub_code(s->pc++);
2008
            break;
2009
        default:
2010
        case 2:
2011
            disp = lduw_code(s->pc);
2012
            s->pc += 2;
2013
            break;
2014
        }
2015
        switch(rm) {
2016
        case 0:
2017
            gen_op_movl_A0_reg(R_EBX);
2018
            gen_op_addl_A0_reg_sN(0, R_ESI);
2019
            break;
2020
        case 1:
2021
            gen_op_movl_A0_reg(R_EBX);
2022
            gen_op_addl_A0_reg_sN(0, R_EDI);
2023
            break;
2024
        case 2:
2025
            gen_op_movl_A0_reg(R_EBP);
2026
            gen_op_addl_A0_reg_sN(0, R_ESI);
2027
            break;
2028
        case 3:
2029
            gen_op_movl_A0_reg(R_EBP);
2030
            gen_op_addl_A0_reg_sN(0, R_EDI);
2031
            break;
2032
        case 4:
2033
            gen_op_movl_A0_reg(R_ESI);
2034
            break;
2035
        case 5:
2036
            gen_op_movl_A0_reg(R_EDI);
2037
            break;
2038
        case 6:
2039
            gen_op_movl_A0_reg(R_EBP);
2040
            break;
2041
        default:
2042
        case 7:
2043
            gen_op_movl_A0_reg(R_EBX);
2044
            break;
2045
        }
2046
        if (disp != 0)
2047
            gen_op_addl_A0_im(disp);
2048
        gen_op_andl_A0_ffff();
2049
    no_rm:
2050
        if (must_add_seg) {
2051
            if (override < 0) {
2052
                if (rm == 2 || rm == 3 || rm == 6)
2053
                    override = R_SS;
2054
                else
2055
                    override = R_DS;
2056
            }
2057
            gen_op_addl_A0_seg(override);
2058
        }
2059
    }
2060

    
2061
    opreg = OR_A0;
2062
    disp = 0;
2063
    *reg_ptr = opreg;
2064
    *offset_ptr = disp;
2065
}
2066

    
2067
static void gen_nop_modrm(DisasContext *s, int modrm)
2068
{
2069
    int mod, rm, base, code;
2070

    
2071
    mod = (modrm >> 6) & 3;
2072
    if (mod == 3)
2073
        return;
2074
    rm = modrm & 7;
2075

    
2076
    if (s->aflag) {
2077

    
2078
        base = rm;
2079

    
2080
        if (base == 4) {
2081
            code = ldub_code(s->pc++);
2082
            base = (code & 7);
2083
        }
2084

    
2085
        switch (mod) {
2086
        case 0:
2087
            if (base == 5) {
2088
                s->pc += 4;
2089
            }
2090
            break;
2091
        case 1:
2092
            s->pc++;
2093
            break;
2094
        default:
2095
        case 2:
2096
            s->pc += 4;
2097
            break;
2098
        }
2099
    } else {
2100
        switch (mod) {
2101
        case 0:
2102
            if (rm == 6) {
2103
                s->pc += 2;
2104
            }
2105
            break;
2106
        case 1:
2107
            s->pc++;
2108
            break;
2109
        default:
2110
        case 2:
2111
            s->pc += 2;
2112
            break;
2113
        }
2114
    }
2115
}
2116

    
2117
/* used for LEA and MOV AX, mem */
2118
static void gen_add_A0_ds_seg(DisasContext *s)
2119
{
2120
    int override, must_add_seg;
2121
    must_add_seg = s->addseg;
2122
    override = R_DS;
2123
    if (s->override >= 0) {
2124
        override = s->override;
2125
        must_add_seg = 1;
2126
    } else {
2127
        override = R_DS;
2128
    }
2129
    if (must_add_seg) {
2130
#ifdef TARGET_X86_64
2131
        if (CODE64(s)) {
2132
            gen_op_addq_A0_seg(override);
2133
        } else
2134
#endif
2135
        {
2136
            gen_op_addl_A0_seg(override);
2137
        }
2138
    }
2139
}
2140

    
2141
/* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2142
   OR_TMP0 */
2143
static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
2144
{
2145
    int mod, rm, opreg, disp;
2146

    
2147
    mod = (modrm >> 6) & 3;
2148
    rm = (modrm & 7) | REX_B(s);
2149
    if (mod == 3) {
2150
        if (is_store) {
2151
            if (reg != OR_TMP0)
2152
                gen_op_mov_TN_reg(ot, 0, reg);
2153
            gen_op_mov_reg_T0(ot, rm);
2154
        } else {
2155
            gen_op_mov_TN_reg(ot, 0, rm);
2156
            if (reg != OR_TMP0)
2157
                gen_op_mov_reg_T0(ot, reg);
2158
        }
2159
    } else {
2160
        gen_lea_modrm(s, modrm, &opreg, &disp);
2161
        if (is_store) {
2162
            if (reg != OR_TMP0)
2163
                gen_op_mov_TN_reg(ot, 0, reg);
2164
            gen_op_st_T0_A0(ot + s->mem_index);
2165
        } else {
2166
            gen_op_ld_T0_A0(ot + s->mem_index);
2167
            if (reg != OR_TMP0)
2168
                gen_op_mov_reg_T0(ot, reg);
2169
        }
2170
    }
2171
}
2172

    
2173
static inline uint32_t insn_get(DisasContext *s, int ot)
2174
{
2175
    uint32_t ret;
2176

    
2177
    switch(ot) {
2178
    case OT_BYTE:
2179
        ret = ldub_code(s->pc);
2180
        s->pc++;
2181
        break;
2182
    case OT_WORD:
2183
        ret = lduw_code(s->pc);
2184
        s->pc += 2;
2185
        break;
2186
    default:
2187
    case OT_LONG:
2188
        ret = ldl_code(s->pc);
2189
        s->pc += 4;
2190
        break;
2191
    }
2192
    return ret;
2193
}
2194

    
2195
static inline int insn_const_size(unsigned int ot)
2196
{
2197
    if (ot <= OT_LONG)
2198
        return 1 << ot;
2199
    else
2200
        return 4;
2201
}
2202

    
2203
static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
2204
{
2205
    TranslationBlock *tb;
2206
    target_ulong pc;
2207

    
2208
    pc = s->cs_base + eip;
2209
    tb = s->tb;
2210
    /* NOTE: we handle the case where the TB spans two pages here */
2211
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
2212
        (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
2213
        /* jump to same page: we can use a direct jump */
2214
        tcg_gen_goto_tb(tb_num);
2215
        gen_jmp_im(eip);
2216
        tcg_gen_exit_tb((long)tb + tb_num);
2217
    } else {
2218
        /* jump to another page: currently not optimized */
2219
        gen_jmp_im(eip);
2220
        gen_eob(s);
2221
    }
2222
}
2223

    
2224
static inline void gen_jcc(DisasContext *s, int b,
2225
                           target_ulong val, target_ulong next_eip)
2226
{
2227
    int l1, l2, cc_op;
2228

    
2229
    cc_op = s->cc_op;
2230
    if (s->cc_op != CC_OP_DYNAMIC) {
2231
        gen_op_set_cc_op(s->cc_op);
2232
        s->cc_op = CC_OP_DYNAMIC;
2233
    }
2234
    if (s->jmp_opt) {
2235
        l1 = gen_new_label();
2236
        gen_jcc1(s, cc_op, b, l1);
2237
        
2238
        gen_goto_tb(s, 0, next_eip);
2239

    
2240
        gen_set_label(l1);
2241
        gen_goto_tb(s, 1, val);
2242
        s->is_jmp = 3;
2243
    } else {
2244

    
2245
        l1 = gen_new_label();
2246
        l2 = gen_new_label();
2247
        gen_jcc1(s, cc_op, b, l1);
2248

    
2249
        gen_jmp_im(next_eip);
2250
        tcg_gen_br(l2);
2251

    
2252
        gen_set_label(l1);
2253
        gen_jmp_im(val);
2254
        gen_set_label(l2);
2255
        gen_eob(s);
2256
    }
2257
}
2258

    
2259
static void gen_setcc(DisasContext *s, int b)
2260
{
2261
    int inv, jcc_op, l1;
2262
    TCGv t0;
2263

    
2264
    if (is_fast_jcc_case(s, b)) {
2265
        /* nominal case: we use a jump */
2266
        /* XXX: make it faster by adding new instructions in TCG */
2267
        t0 = tcg_temp_local_new();
2268
        tcg_gen_movi_tl(t0, 0);
2269
        l1 = gen_new_label();
2270
        gen_jcc1(s, s->cc_op, b ^ 1, l1);
2271
        tcg_gen_movi_tl(t0, 1);
2272
        gen_set_label(l1);
2273
        tcg_gen_mov_tl(cpu_T[0], t0);
2274
        tcg_temp_free(t0);
2275
    } else {
2276
        /* slow case: it is more efficient not to generate a jump,
2277
           although it is questionnable whether this optimization is
2278
           worth to */
2279
        inv = b & 1;
2280
        jcc_op = (b >> 1) & 7;
2281
        gen_setcc_slow_T0(s, jcc_op);
2282
        if (inv) {
2283
            tcg_gen_xori_tl(cpu_T[0], cpu_T[0], 1);
2284
        }
2285
    }
2286
}
2287

    
2288
static inline void gen_op_movl_T0_seg(int seg_reg)
2289
{
2290
    tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
2291
                     offsetof(CPUX86State,segs[seg_reg].selector));
2292
}
2293

    
2294
static inline void gen_op_movl_seg_T0_vm(int seg_reg)
2295
{
2296
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
2297
    tcg_gen_st32_tl(cpu_T[0], cpu_env, 
2298
                    offsetof(CPUX86State,segs[seg_reg].selector));
2299
    tcg_gen_shli_tl(cpu_T[0], cpu_T[0], 4);
2300
    tcg_gen_st_tl(cpu_T[0], cpu_env, 
2301
                  offsetof(CPUX86State,segs[seg_reg].base));
2302
}
2303

    
2304
/* move T0 to seg_reg and compute if the CPU state may change. Never
2305
   call this function with seg_reg == R_CS */
2306
static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
2307
{
2308
    if (s->pe && !s->vm86) {
2309
        /* XXX: optimize by finding processor state dynamically */
2310
        if (s->cc_op != CC_OP_DYNAMIC)
2311
            gen_op_set_cc_op(s->cc_op);
2312
        gen_jmp_im(cur_eip);
2313
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
2314
        gen_helper_load_seg(tcg_const_i32(seg_reg), cpu_tmp2_i32);
2315
        /* abort translation because the addseg value may change or
2316
           because ss32 may change. For R_SS, translation must always
2317
           stop as a special handling must be done to disable hardware
2318
           interrupts for the next instruction */
2319
        if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
2320
            s->is_jmp = 3;
2321
    } else {
2322
        gen_op_movl_seg_T0_vm(seg_reg);
2323
        if (seg_reg == R_SS)
2324
            s->is_jmp = 3;
2325
    }
2326
}
2327

    
2328
static inline int svm_is_rep(int prefixes)
2329
{
2330
    return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
2331
}
2332

    
2333
static inline void
2334
gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2335
                              uint32_t type, uint64_t param)
2336
{
2337
    /* no SVM activated; fast case */
2338
    if (likely(!(s->flags & HF_SVMI_MASK)))
2339
        return;
2340
    if (s->cc_op != CC_OP_DYNAMIC)
2341
        gen_op_set_cc_op(s->cc_op);
2342
    gen_jmp_im(pc_start - s->cs_base);
2343
    gen_helper_svm_check_intercept_param(tcg_const_i32(type),
2344
                                         tcg_const_i64(param));
2345
}
2346

    
2347
static inline void
2348
gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
2349
{
2350
    gen_svm_check_intercept_param(s, pc_start, type, 0);
2351
}
2352

    
2353
static inline void gen_stack_update(DisasContext *s, int addend)
2354
{
2355
#ifdef TARGET_X86_64
2356
    if (CODE64(s)) {
2357
        gen_op_add_reg_im(2, R_ESP, addend);
2358
    } else
2359
#endif
2360
    if (s->ss32) {
2361
        gen_op_add_reg_im(1, R_ESP, addend);
2362
    } else {
2363
        gen_op_add_reg_im(0, R_ESP, addend);
2364
    }
2365
}
2366

    
2367
/* generate a push. It depends on ss32, addseg and dflag */
2368
static void gen_push_T0(DisasContext *s)
2369
{
2370
#ifdef TARGET_X86_64
2371
    if (CODE64(s)) {
2372
        gen_op_movq_A0_reg(R_ESP);
2373
        if (s->dflag) {
2374
            gen_op_addq_A0_im(-8);
2375
            gen_op_st_T0_A0(OT_QUAD + s->mem_index);
2376
        } else {
2377
            gen_op_addq_A0_im(-2);
2378
            gen_op_st_T0_A0(OT_WORD + s->mem_index);
2379
        }
2380
        gen_op_mov_reg_A0(2, R_ESP);
2381
    } else
2382
#endif
2383
    {
2384
        gen_op_movl_A0_reg(R_ESP);
2385
        if (!s->dflag)
2386
            gen_op_addl_A0_im(-2);
2387
        else
2388
            gen_op_addl_A0_im(-4);
2389
        if (s->ss32) {
2390
            if (s->addseg) {
2391
                tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2392
                gen_op_addl_A0_seg(R_SS);
2393
            }
2394
        } else {
2395
            gen_op_andl_A0_ffff();
2396
            tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2397
            gen_op_addl_A0_seg(R_SS);
2398
        }
2399
        gen_op_st_T0_A0(s->dflag + 1 + s->mem_index);
2400
        if (s->ss32 && !s->addseg)
2401
            gen_op_mov_reg_A0(1, R_ESP);
2402
        else
2403
            gen_op_mov_reg_T1(s->ss32 + 1, R_ESP);
2404
    }
2405
}
2406

    
2407
/* generate a push. It depends on ss32, addseg and dflag */
2408
/* slower version for T1, only used for call Ev */
2409
static void gen_push_T1(DisasContext *s)
2410
{
2411
#ifdef TARGET_X86_64
2412
    if (CODE64(s)) {
2413
        gen_op_movq_A0_reg(R_ESP);
2414
        if (s->dflag) {
2415
            gen_op_addq_A0_im(-8);
2416
            gen_op_st_T1_A0(OT_QUAD + s->mem_index);
2417
        } else {
2418
            gen_op_addq_A0_im(-2);
2419
            gen_op_st_T0_A0(OT_WORD + s->mem_index);
2420
        }
2421
        gen_op_mov_reg_A0(2, R_ESP);
2422
    } else
2423
#endif
2424
    {
2425
        gen_op_movl_A0_reg(R_ESP);
2426
        if (!s->dflag)
2427
            gen_op_addl_A0_im(-2);
2428
        else
2429
            gen_op_addl_A0_im(-4);
2430
        if (s->ss32) {
2431
            if (s->addseg) {
2432
                gen_op_addl_A0_seg(R_SS);
2433
            }
2434
        } else {
2435
            gen_op_andl_A0_ffff();
2436
            gen_op_addl_A0_seg(R_SS);
2437
        }
2438
        gen_op_st_T1_A0(s->dflag + 1 + s->mem_index);
2439

    
2440
        if (s->ss32 && !s->addseg)
2441
            gen_op_mov_reg_A0(1, R_ESP);
2442
        else
2443
            gen_stack_update(s, (-2) << s->dflag);
2444
    }
2445
}
2446

    
2447
/* two step pop is necessary for precise exceptions */
2448
static void gen_pop_T0(DisasContext *s)
2449
{
2450
#ifdef TARGET_X86_64
2451
    if (CODE64(s)) {
2452
        gen_op_movq_A0_reg(R_ESP);
2453
        gen_op_ld_T0_A0((s->dflag ? OT_QUAD : OT_WORD) + s->mem_index);
2454
    } else
2455
#endif
2456
    {
2457
        gen_op_movl_A0_reg(R_ESP);
2458
        if (s->ss32) {
2459
            if (s->addseg)
2460
                gen_op_addl_A0_seg(R_SS);
2461
        } else {
2462
            gen_op_andl_A0_ffff();
2463
            gen_op_addl_A0_seg(R_SS);
2464
        }
2465
        gen_op_ld_T0_A0(s->dflag + 1 + s->mem_index);
2466
    }
2467
}
2468

    
2469
static void gen_pop_update(DisasContext *s)
2470
{
2471
#ifdef TARGET_X86_64
2472
    if (CODE64(s) && s->dflag) {
2473
        gen_stack_update(s, 8);
2474
    } else
2475
#endif
2476
    {
2477
        gen_stack_update(s, 2 << s->dflag);
2478
    }
2479
}
2480

    
2481
static void gen_stack_A0(DisasContext *s)
2482
{
2483
    gen_op_movl_A0_reg(R_ESP);
2484
    if (!s->ss32)
2485
        gen_op_andl_A0_ffff();
2486
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2487
    if (s->addseg)
2488
        gen_op_addl_A0_seg(R_SS);
2489
}
2490

    
2491
/* NOTE: wrap around in 16 bit not fully handled */
2492
static void gen_pusha(DisasContext *s)
2493
{
2494
    int i;
2495
    gen_op_movl_A0_reg(R_ESP);
2496
    gen_op_addl_A0_im(-16 <<  s->dflag);
2497
    if (!s->ss32)
2498
        gen_op_andl_A0_ffff();
2499
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2500
    if (s->addseg)
2501
        gen_op_addl_A0_seg(R_SS);
2502
    for(i = 0;i < 8; i++) {
2503
        gen_op_mov_TN_reg(OT_LONG, 0, 7 - i);
2504
        gen_op_st_T0_A0(OT_WORD + s->dflag + s->mem_index);
2505
        gen_op_addl_A0_im(2 <<  s->dflag);
2506
    }
2507
    gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2508
}
2509

    
2510
/* NOTE: wrap around in 16 bit not fully handled */
2511
static void gen_popa(DisasContext *s)
2512
{
2513
    int i;
2514
    gen_op_movl_A0_reg(R_ESP);
2515
    if (!s->ss32)
2516
        gen_op_andl_A0_ffff();
2517
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2518
    tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 16 <<  s->dflag);
2519
    if (s->addseg)
2520
        gen_op_addl_A0_seg(R_SS);
2521
    for(i = 0;i < 8; i++) {
2522
        /* ESP is not reloaded */
2523
        if (i != 3) {
2524
            gen_op_ld_T0_A0(OT_WORD + s->dflag + s->mem_index);
2525
            gen_op_mov_reg_T0(OT_WORD + s->dflag, 7 - i);
2526
        }
2527
        gen_op_addl_A0_im(2 <<  s->dflag);
2528
    }
2529
    gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2530
}
2531

    
2532
static void gen_enter(DisasContext *s, int esp_addend, int level)
2533
{
2534
    int ot, opsize;
2535

    
2536
    level &= 0x1f;
2537
#ifdef TARGET_X86_64
2538
    if (CODE64(s)) {
2539
        ot = s->dflag ? OT_QUAD : OT_WORD;
2540
        opsize = 1 << ot;
2541

    
2542
        gen_op_movl_A0_reg(R_ESP);
2543
        gen_op_addq_A0_im(-opsize);
2544
        tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2545

    
2546
        /* push bp */
2547
        gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
2548
        gen_op_st_T0_A0(ot + s->mem_index);
2549
        if (level) {
2550
            /* XXX: must save state */
2551
            gen_helper_enter64_level(tcg_const_i32(level),
2552
                                     tcg_const_i32((ot == OT_QUAD)),
2553
                                     cpu_T[1]);
2554
        }
2555
        gen_op_mov_reg_T1(ot, R_EBP);
2556
        tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2557
        gen_op_mov_reg_T1(OT_QUAD, R_ESP);
2558
    } else
2559
#endif
2560
    {
2561
        ot = s->dflag + OT_WORD;
2562
        opsize = 2 << s->dflag;
2563

    
2564
        gen_op_movl_A0_reg(R_ESP);
2565
        gen_op_addl_A0_im(-opsize);
2566
        if (!s->ss32)
2567
            gen_op_andl_A0_ffff();
2568
        tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2569
        if (s->addseg)
2570
            gen_op_addl_A0_seg(R_SS);
2571
        /* push bp */
2572
        gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
2573
        gen_op_st_T0_A0(ot + s->mem_index);
2574
        if (level) {
2575
            /* XXX: must save state */
2576
            gen_helper_enter_level(tcg_const_i32(level),
2577
                                   tcg_const_i32(s->dflag),
2578
                                   cpu_T[1]);
2579
        }
2580
        gen_op_mov_reg_T1(ot, R_EBP);
2581
        tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2582
        gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2583
    }
2584
}
2585

    
2586
static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2587
{
2588
    if (s->cc_op != CC_OP_DYNAMIC)
2589
        gen_op_set_cc_op(s->cc_op);
2590
    gen_jmp_im(cur_eip);
2591
    gen_helper_raise_exception(tcg_const_i32(trapno));
2592
    s->is_jmp = 3;
2593
}
2594

    
2595
/* an interrupt is different from an exception because of the
2596
   privilege checks */
2597
static void gen_interrupt(DisasContext *s, int intno,
2598
                          target_ulong cur_eip, target_ulong next_eip)
2599
{
2600
    if (s->cc_op != CC_OP_DYNAMIC)
2601
        gen_op_set_cc_op(s->cc_op);
2602
    gen_jmp_im(cur_eip);
2603
    gen_helper_raise_interrupt(tcg_const_i32(intno), 
2604
                               tcg_const_i32(next_eip - cur_eip));
2605
    s->is_jmp = 3;
2606
}
2607

    
2608
static void gen_debug(DisasContext *s, target_ulong cur_eip)
2609
{
2610
    if (s->cc_op != CC_OP_DYNAMIC)
2611
        gen_op_set_cc_op(s->cc_op);
2612
    gen_jmp_im(cur_eip);
2613
    gen_helper_debug();
2614
    s->is_jmp = 3;
2615
}
2616

    
2617
/* generate a generic end of block. Trace exception is also generated
2618
   if needed */
2619
static void gen_eob(DisasContext *s)
2620
{
2621
    if (s->cc_op != CC_OP_DYNAMIC)
2622
        gen_op_set_cc_op(s->cc_op);
2623
    if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
2624
        gen_helper_reset_inhibit_irq();
2625
    }
2626
    if (s->singlestep_enabled) {
2627
        gen_helper_debug();
2628
    } else if (s->tf) {
2629
        gen_helper_single_step();
2630
    } else {
2631
        tcg_gen_exit_tb(0);
2632
    }
2633
    s->is_jmp = 3;
2634
}
2635

    
2636
/* generate a jump to eip. No segment change must happen before as a
2637
   direct call to the next block may occur */
2638
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2639
{
2640
    if (s->jmp_opt) {
2641
        if (s->cc_op != CC_OP_DYNAMIC) {
2642
            gen_op_set_cc_op(s->cc_op);
2643
            s->cc_op = CC_OP_DYNAMIC;
2644
        }
2645
        gen_goto_tb(s, tb_num, eip);
2646
        s->is_jmp = 3;
2647
    } else {
2648
        gen_jmp_im(eip);
2649
        gen_eob(s);
2650
    }
2651
}
2652

    
2653
static void gen_jmp(DisasContext *s, target_ulong eip)
2654
{
2655
    gen_jmp_tb(s, eip, 0);
2656
}
2657

    
2658
static inline void gen_ldq_env_A0(int idx, int offset)
2659
{
2660
    int mem_index = (idx >> 2) - 1;
2661
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2662
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
2663
}
2664

    
2665
static inline void gen_stq_env_A0(int idx, int offset)
2666
{
2667
    int mem_index = (idx >> 2) - 1;
2668
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
2669
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2670
}
2671

    
2672
static inline void gen_ldo_env_A0(int idx, int offset)
2673
{
2674
    int mem_index = (idx >> 2) - 1;
2675
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2676
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2677
    tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2678
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2679
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2680
}
2681

    
2682
static inline void gen_sto_env_A0(int idx, int offset)
2683
{
2684
    int mem_index = (idx >> 2) - 1;
2685
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2686
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2687
    tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2688
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2689
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2690
}
2691

    
2692
static inline void gen_op_movo(int d_offset, int s_offset)
2693
{
2694
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2695
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2696
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + 8);
2697
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + 8);
2698
}
2699

    
2700
static inline void gen_op_movq(int d_offset, int s_offset)
2701
{
2702
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2703
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2704
}
2705

    
2706
static inline void gen_op_movl(int d_offset, int s_offset)
2707
{
2708
    tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
2709
    tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
2710
}
2711

    
2712
static inline void gen_op_movq_env_0(int d_offset)
2713
{
2714
    tcg_gen_movi_i64(cpu_tmp1_i64, 0);
2715
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2716
}
2717

    
2718
#define SSE_SPECIAL ((void *)1)
2719
#define SSE_DUMMY ((void *)2)
2720

    
2721
#define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2722
#define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2723
                     gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2724

    
2725
static void *sse_op_table1[256][4] = {
2726
    /* 3DNow! extensions */
2727
    [0x0e] = { SSE_DUMMY }, /* femms */
2728
    [0x0f] = { SSE_DUMMY }, /* pf... */
2729
    /* pure SSE operations */
2730
    [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2731
    [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2732
    [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2733
    [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
2734
    [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
2735
    [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
2736
    [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */
2737
    [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */
2738

    
2739
    [0x28] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2740
    [0x29] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2741
    [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2742
    [0x2b] = { SSE_SPECIAL, SSE_SPECIAL },  /* movntps, movntpd */
2743
    [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2744
    [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2745
    [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd },
2746
    [0x2f] = { gen_helper_comiss, gen_helper_comisd },
2747
    [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2748
    [0x51] = SSE_FOP(sqrt),
2749
    [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL },
2750
    [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL },
2751
    [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */
2752
    [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */
2753
    [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */
2754
    [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */
2755
    [0x58] = SSE_FOP(add),
2756
    [0x59] = SSE_FOP(mul),
2757
    [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps,
2758
               gen_helper_cvtss2sd, gen_helper_cvtsd2ss },
2759
    [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq },
2760
    [0x5c] = SSE_FOP(sub),
2761
    [0x5d] = SSE_FOP(min),
2762
    [0x5e] = SSE_FOP(div),
2763
    [0x5f] = SSE_FOP(max),
2764

    
2765
    [0xc2] = SSE_FOP(cmpeq),
2766
    [0xc6] = { gen_helper_shufps, gen_helper_shufpd },
2767

    
2768
    [0x38] = { SSE_SPECIAL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* SSSE3/SSE4 */
2769
    [0x3a] = { SSE_SPECIAL, SSE_SPECIAL }, /* SSSE3/SSE4 */
2770

    
2771
    /* MMX ops and their SSE extensions */
2772
    [0x60] = MMX_OP2(punpcklbw),
2773
    [0x61] = MMX_OP2(punpcklwd),
2774
    [0x62] = MMX_OP2(punpckldq),
2775
    [0x63] = MMX_OP2(packsswb),
2776
    [0x64] = MMX_OP2(pcmpgtb),
2777
    [0x65] = MMX_OP2(pcmpgtw),
2778
    [0x66] = MMX_OP2(pcmpgtl),
2779
    [0x67] = MMX_OP2(packuswb),
2780
    [0x68] = MMX_OP2(punpckhbw),
2781
    [0x69] = MMX_OP2(punpckhwd),
2782
    [0x6a] = MMX_OP2(punpckhdq),
2783
    [0x6b] = MMX_OP2(packssdw),
2784
    [0x6c] = { NULL, gen_helper_punpcklqdq_xmm },
2785
    [0x6d] = { NULL, gen_helper_punpckhqdq_xmm },
2786
    [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
2787
    [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
2788
    [0x70] = { gen_helper_pshufw_mmx,
2789
               gen_helper_pshufd_xmm,
2790
               gen_helper_pshufhw_xmm,
2791
               gen_helper_pshuflw_xmm },
2792
    [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
2793
    [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
2794
    [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
2795
    [0x74] = MMX_OP2(pcmpeqb),
2796
    [0x75] = MMX_OP2(pcmpeqw),
2797
    [0x76] = MMX_OP2(pcmpeql),
2798
    [0x77] = { SSE_DUMMY }, /* emms */
2799
    [0x7c] = { NULL, gen_helper_haddpd, NULL, gen_helper_haddps },
2800
    [0x7d] = { NULL, gen_helper_hsubpd, NULL, gen_helper_hsubps },
2801
    [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
2802
    [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
2803
    [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
2804
    [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
2805
    [0xd0] = { NULL, gen_helper_addsubpd, NULL, gen_helper_addsubps },
2806
    [0xd1] = MMX_OP2(psrlw),
2807
    [0xd2] = MMX_OP2(psrld),
2808
    [0xd3] = MMX_OP2(psrlq),
2809
    [0xd4] = MMX_OP2(paddq),
2810
    [0xd5] = MMX_OP2(pmullw),
2811
    [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2812
    [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
2813
    [0xd8] = MMX_OP2(psubusb),
2814
    [0xd9] = MMX_OP2(psubusw),
2815
    [0xda] = MMX_OP2(pminub),
2816
    [0xdb] = MMX_OP2(pand),
2817
    [0xdc] = MMX_OP2(paddusb),
2818
    [0xdd] = MMX_OP2(paddusw),
2819
    [0xde] = MMX_OP2(pmaxub),
2820
    [0xdf] = MMX_OP2(pandn),
2821
    [0xe0] = MMX_OP2(pavgb),
2822
    [0xe1] = MMX_OP2(psraw),
2823
    [0xe2] = MMX_OP2(psrad),
2824
    [0xe3] = MMX_OP2(pavgw),
2825
    [0xe4] = MMX_OP2(pmulhuw),
2826
    [0xe5] = MMX_OP2(pmulhw),
2827
    [0xe6] = { NULL, gen_helper_cvttpd2dq, gen_helper_cvtdq2pd, gen_helper_cvtpd2dq },
2828
    [0xe7] = { SSE_SPECIAL , SSE_SPECIAL },  /* movntq, movntq */
2829
    [0xe8] = MMX_OP2(psubsb),
2830
    [0xe9] = MMX_OP2(psubsw),
2831
    [0xea] = MMX_OP2(pminsw),
2832
    [0xeb] = MMX_OP2(por),
2833
    [0xec] = MMX_OP2(paddsb),
2834
    [0xed] = MMX_OP2(paddsw),
2835
    [0xee] = MMX_OP2(pmaxsw),
2836
    [0xef] = MMX_OP2(pxor),
2837
    [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
2838
    [0xf1] = MMX_OP2(psllw),
2839
    [0xf2] = MMX_OP2(pslld),
2840
    [0xf3] = MMX_OP2(psllq),
2841
    [0xf4] = MMX_OP2(pmuludq),
2842
    [0xf5] = MMX_OP2(pmaddwd),
2843
    [0xf6] = MMX_OP2(psadbw),
2844
    [0xf7] = MMX_OP2(maskmov),
2845
    [0xf8] = MMX_OP2(psubb),
2846
    [0xf9] = MMX_OP2(psubw),
2847
    [0xfa] = MMX_OP2(psubl),
2848
    [0xfb] = MMX_OP2(psubq),
2849
    [0xfc] = MMX_OP2(paddb),
2850
    [0xfd] = MMX_OP2(paddw),
2851
    [0xfe] = MMX_OP2(paddl),
2852
};
2853

    
2854
static void *sse_op_table2[3 * 8][2] = {
2855
    [0 + 2] = MMX_OP2(psrlw),
2856
    [0 + 4] = MMX_OP2(psraw),
2857
    [0 + 6] = MMX_OP2(psllw),
2858
    [8 + 2] = MMX_OP2(psrld),
2859
    [8 + 4] = MMX_OP2(psrad),
2860
    [8 + 6] = MMX_OP2(pslld),
2861
    [16 + 2] = MMX_OP2(psrlq),
2862
    [16 + 3] = { NULL, gen_helper_psrldq_xmm },
2863
    [16 + 6] = MMX_OP2(psllq),
2864
    [16 + 7] = { NULL, gen_helper_pslldq_xmm },
2865
};
2866

    
2867
static void *sse_op_table3[4 * 3] = {
2868
    gen_helper_cvtsi2ss,
2869
    gen_helper_cvtsi2sd,
2870
    X86_64_ONLY(gen_helper_cvtsq2ss),
2871
    X86_64_ONLY(gen_helper_cvtsq2sd),
2872

    
2873
    gen_helper_cvttss2si,
2874
    gen_helper_cvttsd2si,
2875
    X86_64_ONLY(gen_helper_cvttss2sq),
2876
    X86_64_ONLY(gen_helper_cvttsd2sq),
2877

    
2878
    gen_helper_cvtss2si,
2879
    gen_helper_cvtsd2si,
2880
    X86_64_ONLY(gen_helper_cvtss2sq),
2881
    X86_64_ONLY(gen_helper_cvtsd2sq),
2882
};
2883

    
2884
static void *sse_op_table4[8][4] = {
2885
    SSE_FOP(cmpeq),
2886
    SSE_FOP(cmplt),
2887
    SSE_FOP(cmple),
2888
    SSE_FOP(cmpunord),
2889
    SSE_FOP(cmpneq),
2890
    SSE_FOP(cmpnlt),
2891
    SSE_FOP(cmpnle),
2892
    SSE_FOP(cmpord),
2893
};
2894

    
2895
static void *sse_op_table5[256] = {
2896
    [0x0c] = gen_helper_pi2fw,
2897
    [0x0d] = gen_helper_pi2fd,
2898
    [0x1c] = gen_helper_pf2iw,
2899
    [0x1d] = gen_helper_pf2id,
2900
    [0x8a] = gen_helper_pfnacc,
2901
    [0x8e] = gen_helper_pfpnacc,
2902
    [0x90] = gen_helper_pfcmpge,
2903
    [0x94] = gen_helper_pfmin,
2904
    [0x96] = gen_helper_pfrcp,
2905
    [0x97] = gen_helper_pfrsqrt,
2906
    [0x9a] = gen_helper_pfsub,
2907
    [0x9e] = gen_helper_pfadd,
2908
    [0xa0] = gen_helper_pfcmpgt,
2909
    [0xa4] = gen_helper_pfmax,
2910
    [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
2911
    [0xa7] = gen_helper_movq, /* pfrsqit1 */
2912
    [0xaa] = gen_helper_pfsubr,
2913
    [0xae] = gen_helper_pfacc,
2914
    [0xb0] = gen_helper_pfcmpeq,
2915
    [0xb4] = gen_helper_pfmul,
2916
    [0xb6] = gen_helper_movq, /* pfrcpit2 */
2917
    [0xb7] = gen_helper_pmulhrw_mmx,
2918
    [0xbb] = gen_helper_pswapd,
2919
    [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
2920
};
2921

    
2922
struct sse_op_helper_s {
2923
    void *op[2]; uint32_t ext_mask;
2924
};
2925
#define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2926
#define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2927
#define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2928
#define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2929
static struct sse_op_helper_s sse_op_table6[256] = {
2930
    [0x00] = SSSE3_OP(pshufb),
2931
    [0x01] = SSSE3_OP(phaddw),
2932
    [0x02] = SSSE3_OP(phaddd),
2933
    [0x03] = SSSE3_OP(phaddsw),
2934
    [0x04] = SSSE3_OP(pmaddubsw),
2935
    [0x05] = SSSE3_OP(phsubw),
2936
    [0x06] = SSSE3_OP(phsubd),
2937
    [0x07] = SSSE3_OP(phsubsw),
2938
    [0x08] = SSSE3_OP(psignb),
2939
    [0x09] = SSSE3_OP(psignw),
2940
    [0x0a] = SSSE3_OP(psignd),
2941
    [0x0b] = SSSE3_OP(pmulhrsw),
2942
    [0x10] = SSE41_OP(pblendvb),
2943
    [0x14] = SSE41_OP(blendvps),
2944
    [0x15] = SSE41_OP(blendvpd),
2945
    [0x17] = SSE41_OP(ptest),
2946
    [0x1c] = SSSE3_OP(pabsb),
2947
    [0x1d] = SSSE3_OP(pabsw),
2948
    [0x1e] = SSSE3_OP(pabsd),
2949
    [0x20] = SSE41_OP(pmovsxbw),
2950
    [0x21] = SSE41_OP(pmovsxbd),
2951
    [0x22] = SSE41_OP(pmovsxbq),
2952
    [0x23] = SSE41_OP(pmovsxwd),
2953
    [0x24] = SSE41_OP(pmovsxwq),
2954
    [0x25] = SSE41_OP(pmovsxdq),
2955
    [0x28] = SSE41_OP(pmuldq),
2956
    [0x29] = SSE41_OP(pcmpeqq),
2957
    [0x2a] = SSE41_SPECIAL, /* movntqda */
2958
    [0x2b] = SSE41_OP(packusdw),
2959
    [0x30] = SSE41_OP(pmovzxbw),
2960
    [0x31] = SSE41_OP(pmovzxbd),
2961
    [0x32] = SSE41_OP(pmovzxbq),
2962
    [0x33] = SSE41_OP(pmovzxwd),
2963
    [0x34] = SSE41_OP(pmovzxwq),
2964
    [0x35] = SSE41_OP(pmovzxdq),
2965
    [0x37] = SSE42_OP(pcmpgtq),
2966
    [0x38] = SSE41_OP(pminsb),
2967
    [0x39] = SSE41_OP(pminsd),
2968
    [0x3a] = SSE41_OP(pminuw),
2969
    [0x3b] = SSE41_OP(pminud),
2970
    [0x3c] = SSE41_OP(pmaxsb),
2971
    [0x3d] = SSE41_OP(pmaxsd),
2972
    [0x3e] = SSE41_OP(pmaxuw),
2973
    [0x3f] = SSE41_OP(pmaxud),
2974
    [0x40] = SSE41_OP(pmulld),
2975
    [0x41] = SSE41_OP(phminposuw),
2976
};
2977

    
2978
static struct sse_op_helper_s sse_op_table7[256] = {
2979
    [0x08] = SSE41_OP(roundps),
2980
    [0x09] = SSE41_OP(roundpd),
2981
    [0x0a] = SSE41_OP(roundss),
2982
    [0x0b] = SSE41_OP(roundsd),
2983
    [0x0c] = SSE41_OP(blendps),
2984
    [0x0d] = SSE41_OP(blendpd),
2985
    [0x0e] = SSE41_OP(pblendw),
2986
    [0x0f] = SSSE3_OP(palignr),
2987
    [0x14] = SSE41_SPECIAL, /* pextrb */
2988
    [0x15] = SSE41_SPECIAL, /* pextrw */
2989
    [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */
2990
    [0x17] = SSE41_SPECIAL, /* extractps */
2991
    [0x20] = SSE41_SPECIAL, /* pinsrb */
2992
    [0x21] = SSE41_SPECIAL, /* insertps */
2993
    [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */
2994
    [0x40] = SSE41_OP(dpps),
2995
    [0x41] = SSE41_OP(dppd),
2996
    [0x42] = SSE41_OP(mpsadbw),
2997
    [0x60] = SSE42_OP(pcmpestrm),
2998
    [0x61] = SSE42_OP(pcmpestri),
2999
    [0x62] = SSE42_OP(pcmpistrm),
3000
    [0x63] = SSE42_OP(pcmpistri),
3001
};
3002

    
3003
static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
3004
{
3005
    int b1, op1_offset, op2_offset, is_xmm, val, ot;
3006
    int modrm, mod, rm, reg, reg_addr, offset_addr;
3007
    void *sse_op2;
3008

    
3009
    b &= 0xff;
3010
    if (s->prefix & PREFIX_DATA)
3011
        b1 = 1;
3012
    else if (s->prefix & PREFIX_REPZ)
3013
        b1 = 2;
3014
    else if (s->prefix & PREFIX_REPNZ)
3015
        b1 = 3;
3016
    else
3017
        b1 = 0;
3018
    sse_op2 = sse_op_table1[b][b1];
3019
    if (!sse_op2)
3020
        goto illegal_op;
3021
    if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
3022
        is_xmm = 1;
3023
    } else {
3024
        if (b1 == 0) {
3025
            /* MMX case */
3026
            is_xmm = 0;
3027
        } else {
3028
            is_xmm = 1;
3029
        }
3030
    }
3031
    /* simple MMX/SSE operation */
3032
    if (s->flags & HF_TS_MASK) {
3033
        gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
3034
        return;
3035
    }
3036
    if (s->flags & HF_EM_MASK) {
3037
    illegal_op:
3038
        gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
3039
        return;
3040
    }
3041
    if (is_xmm && !(s->flags & HF_OSFXSR_MASK))
3042
        if ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))
3043
            goto illegal_op;
3044
    if (b == 0x0e) {
3045
        if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
3046
            goto illegal_op;
3047
        /* femms */
3048
        gen_helper_emms();
3049
        return;
3050
    }
3051
    if (b == 0x77) {
3052
        /* emms */
3053
        gen_helper_emms();
3054
        return;
3055
    }
3056
    /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3057
       the static cpu state) */
3058
    if (!is_xmm) {
3059
        gen_helper_enter_mmx();
3060
    }
3061

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

    
3577
            sse_op2 = sse_op_table6[b].op[b1];
3578
            if (!sse_op2)
3579
                goto illegal_op;
3580
            if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
3581
                goto illegal_op;
3582

    
3583
            if (b1) {
3584
                op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3585
                if (mod == 3) {
3586
                    op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
3587
                } else {
3588
                    op2_offset = offsetof(CPUX86State,xmm_t0);
3589
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3590
                    switch (b) {
3591
                    case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3592
                    case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3593
                    case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3594
                        gen_ldq_env_A0(s->mem_index, op2_offset +
3595
                                        offsetof(XMMReg, XMM_Q(0)));
3596
                        break;
3597
                    case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3598
                    case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3599
                        tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
3600
                                          (s->mem_index >> 2) - 1);
3601
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
3602
                        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset +
3603
                                        offsetof(XMMReg, XMM_L(0)));
3604
                        break;
3605
                    case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3606
                        tcg_gen_qemu_ld16u(cpu_tmp0, cpu_A0,
3607
                                          (s->mem_index >> 2) - 1);
3608
                        tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset +
3609
                                        offsetof(XMMReg, XMM_W(0)));
3610
                        break;
3611
                    case 0x2a:            /* movntqda */
3612
                        gen_ldo_env_A0(s->mem_index, op1_offset);
3613
                        return;
3614
                    default:
3615
                        gen_ldo_env_A0(s->mem_index, op2_offset);
3616
                    }
3617
                }
3618
            } else {
3619
                op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3620
                if (mod == 3) {
3621
                    op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3622
                } else {
3623
                    op2_offset = offsetof(CPUX86State,mmx_t0);
3624
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3625
                    gen_ldq_env_A0(s->mem_index, op2_offset);
3626
                }
3627
            }
3628
            if (sse_op2 == SSE_SPECIAL)
3629
                goto illegal_op;
3630

    
3631
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3632
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3633
            ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
3634

    
3635
            if (b == 0x17)
3636
                s->cc_op = CC_OP_EFLAGS;
3637
            break;
3638
        case 0x338: /* crc32 */
3639
        crc32:
3640
            b = modrm;
3641
            modrm = ldub_code(s->pc++);
3642
            reg = ((modrm >> 3) & 7) | rex_r;
3643

    
3644
            if (b != 0xf0 && b != 0xf1)
3645
                goto illegal_op;
3646
            if (!(s->cpuid_ext_features & CPUID_EXT_SSE42))
3647
                goto illegal_op;
3648

    
3649
            if (b == 0xf0)
3650
                ot = OT_BYTE;
3651
            else if (b == 0xf1 && s->dflag != 2)
3652
                if (s->prefix & PREFIX_DATA)
3653
                    ot = OT_WORD;
3654
                else
3655
                    ot = OT_LONG;
3656
            else
3657
                ot = OT_QUAD;
3658

    
3659
            gen_op_mov_TN_reg(OT_LONG, 0, reg);
3660
            tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3661
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3662
            gen_helper_crc32(cpu_T[0], cpu_tmp2_i32,
3663
                             cpu_T[0], tcg_const_i32(8 << ot));
3664

    
3665
            ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3666
            gen_op_mov_reg_T0(ot, reg);
3667
            break;
3668
        case 0x03a:
3669
        case 0x13a:
3670
            b = modrm;
3671
            modrm = ldub_code(s->pc++);
3672
            rm = modrm & 7;
3673
            reg = ((modrm >> 3) & 7) | rex_r;
3674
            mod = (modrm >> 6) & 3;
3675

    
3676
            sse_op2 = sse_op_table7[b].op[b1];
3677
            if (!sse_op2)
3678
                goto illegal_op;
3679
            if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
3680
                goto illegal_op;
3681

    
3682
            if (sse_op2 == SSE_SPECIAL) {
3683
                ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3684
                rm = (modrm & 7) | REX_B(s);
3685
                if (mod != 3)
3686
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3687
                reg = ((modrm >> 3) & 7) | rex_r;
3688
                val = ldub_code(s->pc++);
3689
                switch (b) {
3690
                case 0x14: /* pextrb */
3691
                    tcg_gen_ld8u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
3692
                                            xmm_regs[reg].XMM_B(val & 15)));
3693
                    if (mod == 3)
3694
                        gen_op_mov_reg_T0(ot, rm);
3695
                    else
3696
                        tcg_gen_qemu_st8(cpu_T[0], cpu_A0,
3697
                                        (s->mem_index >> 2) - 1);
3698
                    break;
3699
                case 0x15: /* pextrw */
3700
                    tcg_gen_ld16u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
3701
                                            xmm_regs[reg].XMM_W(val & 7)));
3702
                    if (mod == 3)
3703
                        gen_op_mov_reg_T0(ot, rm);
3704
                    else
3705
                        tcg_gen_qemu_st16(cpu_T[0], cpu_A0,
3706
                                        (s->mem_index >> 2) - 1);
3707
                    break;
3708
                case 0x16:
3709
                    if (ot == OT_LONG) { /* pextrd */
3710
                        tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
3711
                                        offsetof(CPUX86State,
3712
                                                xmm_regs[reg].XMM_L(val & 3)));
3713
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3714
                        if (mod == 3)
3715
                            gen_op_mov_reg_v(ot, rm, cpu_T[0]);
3716
                        else
3717
                            tcg_gen_qemu_st32(cpu_T[0], cpu_A0,
3718
                                            (s->mem_index >> 2) - 1);
3719
                    } else { /* pextrq */
3720
#ifdef TARGET_X86_64
3721
                        tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
3722
                                        offsetof(CPUX86State,
3723
                                                xmm_regs[reg].XMM_Q(val & 1)));
3724
                        if (mod == 3)
3725
                            gen_op_mov_reg_v(ot, rm, cpu_tmp1_i64);
3726
                        else
3727
                            tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0,
3728
                                            (s->mem_index >> 2) - 1);
3729
#else
3730
                        goto illegal_op;
3731
#endif
3732
                    }
3733
                    break;
3734
                case 0x17: /* extractps */
3735
                    tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
3736
                                            xmm_regs[reg].XMM_L(val & 3)));
3737
                    if (mod == 3)
3738
                        gen_op_mov_reg_T0(ot, rm);
3739
                    else
3740
                        tcg_gen_qemu_st32(cpu_T[0], cpu_A0,
3741
                                        (s->mem_index >> 2) - 1);
3742
                    break;
3743
                case 0x20: /* pinsrb */
3744
                    if (mod == 3)
3745
                        gen_op_mov_TN_reg(OT_LONG, 0, rm);
3746
                    else
3747
                        tcg_gen_qemu_ld8u(cpu_tmp0, cpu_A0,
3748
                                        (s->mem_index >> 2) - 1);
3749
                    tcg_gen_st8_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State,
3750
                                            xmm_regs[reg].XMM_B(val & 15)));
3751
                    break;
3752
                case 0x21: /* insertps */
3753
                    if (mod == 3) {
3754
                        tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
3755
                                        offsetof(CPUX86State,xmm_regs[rm]
3756
                                                .XMM_L((val >> 6) & 3)));
3757
                    } else {
3758
                        tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
3759
                                        (s->mem_index >> 2) - 1);
3760
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
3761
                    }
3762
                    tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
3763
                                    offsetof(CPUX86State,xmm_regs[reg]
3764
                                            .XMM_L((val >> 4) & 3)));
3765
                    if ((val >> 0) & 1)
3766
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
3767
                                        cpu_env, offsetof(CPUX86State,
3768
                                                xmm_regs[reg].XMM_L(0)));
3769
                    if ((val >> 1) & 1)
3770
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
3771
                                        cpu_env, offsetof(CPUX86State,
3772
                                                xmm_regs[reg].XMM_L(1)));
3773
                    if ((val >> 2) & 1)
3774
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
3775
                                        cpu_env, offsetof(CPUX86State,
3776
                                                xmm_regs[reg].XMM_L(2)));
3777
                    if ((val >> 3) & 1)
3778
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
3779
                                        cpu_env, offsetof(CPUX86State,
3780
                                                xmm_regs[reg].XMM_L(3)));
3781
                    break;
3782
                case 0x22:
3783
                    if (ot == OT_LONG) { /* pinsrd */
3784
                        if (mod == 3)
3785
                            gen_op_mov_v_reg(ot, cpu_tmp0, rm);
3786
                        else
3787
                            tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
3788
                                            (s->mem_index >> 2) - 1);
3789
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
3790
                        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
3791
                                        offsetof(CPUX86State,
3792
                                                xmm_regs[reg].XMM_L(val & 3)));
3793
                    } else { /* pinsrq */
3794
#ifdef TARGET_X86_64
3795
                        if (mod == 3)
3796
                            gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);
3797
                        else
3798
                            tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0,
3799
                                            (s->mem_index >> 2) - 1);
3800
                        tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
3801
                                        offsetof(CPUX86State,
3802
                                                xmm_regs[reg].XMM_Q(val & 1)));
3803
#else
3804
                        goto illegal_op;
3805
#endif
3806
                    }
3807
                    break;
3808
                }
3809
                return;
3810
            }
3811

    
3812
            if (b1) {
3813
                op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3814
                if (mod == 3) {
3815
                    op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
3816
                } else {
3817
                    op2_offset = offsetof(CPUX86State,xmm_t0);
3818
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3819
                    gen_ldo_env_A0(s->mem_index, op2_offset);
3820
                }
3821
            } else {
3822
                op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3823
                if (mod == 3) {
3824
                    op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3825
                } else {
3826
                    op2_offset = offsetof(CPUX86State,mmx_t0);
3827
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3828
                    gen_ldq_env_A0(s->mem_index, op2_offset);
3829
                }
3830
            }
3831
            val = ldub_code(s->pc++);
3832

    
3833
            if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
3834
                s->cc_op = CC_OP_EFLAGS;
3835

    
3836
                if (s->dflag == 2)
3837
                    /* The helper must use entire 64-bit gp registers */
3838
                    val |= 1 << 8;
3839
            }
3840

    
3841
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3842
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3843
            ((void (*)(TCGv_ptr, TCGv_ptr, TCGv_i32))sse_op2)(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
3844
            break;
3845
        default:
3846
            goto illegal_op;
3847
        }
3848
    } else {
3849
        /* generic MMX or SSE operation */
3850
        switch(b) {
3851
        case 0x70: /* pshufx insn */
3852
        case 0xc6: /* pshufx insn */
3853
        case 0xc2: /* compare insns */
3854
            s->rip_offset = 1;
3855
            break;
3856
        default:
3857
            break;
3858
        }
3859
        if (is_xmm) {
3860
            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3861
            if (mod != 3) {
3862
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3863
                op2_offset = offsetof(CPUX86State,xmm_t0);
3864
                if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f && b != 0x5b) ||
3865
                                b == 0xc2)) {
3866
                    /* specific case for SSE single instructions */
3867
                    if (b1 == 2) {
3868
                        /* 32 bit access */
3869
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
3870
                        tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
3871
                    } else {
3872
                        /* 64 bit access */
3873
                        gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_D(0)));
3874
                    }
3875
                } else {
3876
                    gen_ldo_env_A0(s->mem_index, op2_offset);
3877
                }
3878
            } else {
3879
                rm = (modrm & 7) | REX_B(s);
3880
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3881
            }
3882
        } else {
3883
            op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3884
            if (mod != 3) {
3885
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3886
                op2_offset = offsetof(CPUX86State,mmx_t0);
3887
                gen_ldq_env_A0(s->mem_index, op2_offset);
3888
            } else {
3889
                rm = (modrm & 7);
3890
                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3891
            }
3892
        }
3893
        switch(b) {
3894
        case 0x0f: /* 3DNow! data insns */
3895
            if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
3896
                goto illegal_op;
3897
            val = ldub_code(s->pc++);
3898
            sse_op2 = sse_op_table5[val];
3899
            if (!sse_op2)
3900
                goto illegal_op;
3901
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3902
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3903
            ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
3904
            break;
3905
        case 0x70: /* pshufx insn */
3906
        case 0xc6: /* pshufx insn */
3907
            val = ldub_code(s->pc++);
3908
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3909
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3910
            ((void (*)(TCGv_ptr, TCGv_ptr, TCGv_i32))sse_op2)(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
3911
            break;
3912
        case 0xc2:
3913
            /* compare insns */
3914
            val = ldub_code(s->pc++);
3915
            if (val >= 8)
3916
                goto illegal_op;
3917
            sse_op2 = sse_op_table4[val][b1];
3918
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3919
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3920
            ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
3921
            break;
3922
        case 0xf7:
3923
            /* maskmov : we must prepare A0 */
3924
            if (mod != 3)
3925
                goto illegal_op;
3926
#ifdef TARGET_X86_64
3927
            if (s->aflag == 2) {
3928
                gen_op_movq_A0_reg(R_EDI);
3929
            } else
3930
#endif
3931
            {
3932
                gen_op_movl_A0_reg(R_EDI);
3933
                if (s->aflag == 0)
3934
                    gen_op_andl_A0_ffff();
3935
            }
3936
            gen_add_A0_ds_seg(s);
3937

    
3938
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3939
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3940
            ((void (*)(TCGv_ptr, TCGv_ptr, TCGv))sse_op2)(cpu_ptr0, cpu_ptr1, cpu_A0);
3941
            break;
3942
        default:
3943
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3944
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3945
            ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
3946
            break;
3947
        }
3948
        if (b == 0x2e || b == 0x2f) {
3949
            s->cc_op = CC_OP_EFLAGS;
3950
        }
3951
    }
3952
}
3953

    
3954
/* convert one instruction. s->is_jmp is set if the translation must
3955
   be stopped. Return the next pc value */
3956
static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
3957
{
3958
    int b, prefixes, aflag, dflag;
3959
    int shift, ot;
3960
    int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
3961
    target_ulong next_eip, tval;
3962
    int rex_w, rex_r;
3963

    
3964
    if (unlikely(loglevel & CPU_LOG_TB_OP))
3965
        tcg_gen_debug_insn_start(pc_start);
3966
    s->pc = pc_start;
3967
    prefixes = 0;
3968
    aflag = s->code32;
3969
    dflag = s->code32;
3970
    s->override = -1;
3971
    rex_w = -1;
3972
    rex_r = 0;
3973
#ifdef TARGET_X86_64
3974
    s->rex_x = 0;
3975
    s->rex_b = 0;
3976
    x86_64_hregs = 0;
3977
#endif
3978
    s->rip_offset = 0; /* for relative ip address */
3979
 next_byte:
3980
    b = ldub_code(s->pc);
3981
    s->pc++;
3982
    /* check prefixes */
3983
#ifdef TARGET_X86_64
3984
    if (CODE64(s)) {
3985
        switch (b) {
3986
        case 0xf3:
3987
            prefixes |= PREFIX_REPZ;
3988
            goto next_byte;
3989
        case 0xf2:
3990
            prefixes |= PREFIX_REPNZ;
3991
            goto next_byte;
3992
        case 0xf0:
3993
            prefixes |= PREFIX_LOCK;
3994
            goto next_byte;
3995
        case 0x2e:
3996
            s->override = R_CS;
3997
            goto next_byte;
3998
        case 0x36:
3999
            s->override = R_SS;
4000
            goto next_byte;
4001
        case 0x3e:
4002
            s->override = R_DS;
4003
            goto next_byte;
4004
        case 0x26:
4005
            s->override = R_ES;
4006
            goto next_byte;
4007
        case 0x64:
4008
            s->override = R_FS;
4009
            goto next_byte;
4010
        case 0x65:
4011
            s->override = R_GS;
4012
            goto next_byte;
4013
        case 0x66:
4014
            prefixes |= PREFIX_DATA;
4015
            goto next_byte;
4016
        case 0x67:
4017
            prefixes |= PREFIX_ADR;
4018
            goto next_byte;
4019
        case 0x40 ... 0x4f:
4020
            /* REX prefix */
4021
            rex_w = (b >> 3) & 1;
4022
            rex_r = (b & 0x4) << 1;
4023
            s->rex_x = (b & 0x2) << 2;
4024
            REX_B(s) = (b & 0x1) << 3;
4025
            x86_64_hregs = 1; /* select uniform byte register addressing */
4026
            goto next_byte;
4027
        }
4028
        if (rex_w == 1) {
4029
            /* 0x66 is ignored if rex.w is set */
4030
            dflag = 2;
4031
        } else {
4032
            if (prefixes & PREFIX_DATA)
4033
                dflag ^= 1;
4034
        }
4035
        if (!(prefixes & PREFIX_ADR))
4036
            aflag = 2;
4037
    } else
4038
#endif
4039
    {
4040
        switch (b) {
4041
        case 0xf3:
4042
            prefixes |= PREFIX_REPZ;
4043
            goto next_byte;
4044
        case 0xf2:
4045
            prefixes |= PREFIX_REPNZ;
4046
            goto next_byte;
4047
        case 0xf0:
4048
            prefixes |= PREFIX_LOCK;
4049
            goto next_byte;
4050
        case 0x2e:
4051
            s->override = R_CS;
4052
            goto next_byte;
4053
        case 0x36:
4054
            s->override = R_SS;
4055
            goto next_byte;
4056
        case 0x3e:
4057
            s->override = R_DS;
4058
            goto next_byte;
4059
        case 0x26:
4060
            s->override = R_ES;
4061
            goto next_byte;
4062
        case 0x64:
4063
            s->override = R_FS;
4064
            goto next_byte;
4065
        case 0x65:
4066
            s->override = R_GS;
4067
            goto next_byte;
4068
        case 0x66:
4069
            prefixes |= PREFIX_DATA;
4070
            goto next_byte;
4071
        case 0x67:
4072
            prefixes |= PREFIX_ADR;
4073
            goto next_byte;
4074
        }
4075
        if (prefixes & PREFIX_DATA)
4076
            dflag ^= 1;
4077
        if (prefixes & PREFIX_ADR)
4078
            aflag ^= 1;
4079
    }
4080

    
4081
    s->prefix = prefixes;
4082
    s->aflag = aflag;
4083
    s->dflag = dflag;
4084

    
4085
    /* lock generation */
4086
    if (prefixes & PREFIX_LOCK)
4087
        gen_helper_lock();
4088

    
4089
    /* now check op code */
4090
 reswitch:
4091
    switch(b) {
4092
    case 0x0f:
4093
        /**************************/
4094
        /* extended op code */
4095
        b = ldub_code(s->pc++) | 0x100;
4096
        goto reswitch;
4097

    
4098
        /**************************/
4099
        /* arith & logic */
4100
    case 0x00 ... 0x05:
4101
    case 0x08 ... 0x0d:
4102
    case 0x10 ... 0x15:
4103
    case 0x18 ... 0x1d:
4104
    case 0x20 ... 0x25:
4105
    case 0x28 ... 0x2d:
4106
    case 0x30 ... 0x35:
4107
    case 0x38 ... 0x3d:
4108
        {
4109
            int op, f, val;
4110
            op = (b >> 3) & 7;
4111
            f = (b >> 1) & 3;
4112

    
4113
            if ((b & 1) == 0)
4114
                ot = OT_BYTE;
4115
            else
4116
                ot = dflag + OT_WORD;
4117

    
4118
            switch(f) {
4119
            case 0: /* OP Ev, Gv */
4120
                modrm = ldub_code(s->pc++);
4121
                reg = ((modrm >> 3) & 7) | rex_r;
4122
                mod = (modrm >> 6) & 3;
4123
                rm = (modrm & 7) | REX_B(s);
4124
                if (mod != 3) {
4125
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4126
                    opreg = OR_TMP0;
4127
                } else if (op == OP_XORL && rm == reg) {
4128
                xor_zero:
4129
                    /* xor reg, reg optimisation */
4130
                    gen_op_movl_T0_0();
4131
                    s->cc_op = CC_OP_LOGICB + ot;
4132
                    gen_op_mov_reg_T0(ot, reg);
4133
                    gen_op_update1_cc();
4134
                    break;
4135
                } else {
4136
                    opreg = rm;
4137
                }
4138
                gen_op_mov_TN_reg(ot, 1, reg);
4139
                gen_op(s, op, ot, opreg);
4140
                break;
4141
            case 1: /* OP Gv, Ev */
4142
                modrm = ldub_code(s->pc++);
4143
                mod = (modrm >> 6) & 3;
4144
                reg = ((modrm >> 3) & 7) | rex_r;
4145
                rm = (modrm & 7) | REX_B(s);
4146
                if (mod != 3) {
4147
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4148
                    gen_op_ld_T1_A0(ot + s->mem_index);
4149
                } else if (op == OP_XORL && rm == reg) {
4150
                    goto xor_zero;
4151
                } else {
4152
                    gen_op_mov_TN_reg(ot, 1, rm);
4153
                }
4154
                gen_op(s, op, ot, reg);
4155
                break;
4156
            case 2: /* OP A, Iv */
4157
                val = insn_get(s, ot);
4158
                gen_op_movl_T1_im(val);
4159
                gen_op(s, op, ot, OR_EAX);
4160
                break;
4161
            }
4162
        }
4163
        break;
4164

    
4165
    case 0x82:
4166
        if (CODE64(s))
4167
            goto illegal_op;
4168
    case 0x80: /* GRP1 */
4169
    case 0x81:
4170
    case 0x83:
4171
        {
4172
            int val;
4173

    
4174
            if ((b & 1) == 0)
4175
                ot = OT_BYTE;
4176
            else
4177
                ot = dflag + OT_WORD;
4178

    
4179
            modrm = ldub_code(s->pc++);
4180
            mod = (modrm >> 6) & 3;
4181
            rm = (modrm & 7) | REX_B(s);
4182
            op = (modrm >> 3) & 7;
4183

    
4184
            if (mod != 3) {
4185
                if (b == 0x83)
4186
                    s->rip_offset = 1;
4187
                else
4188
                    s->rip_offset = insn_const_size(ot);
4189
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4190
                opreg = OR_TMP0;
4191
            } else {
4192
                opreg = rm;
4193
            }
4194

    
4195
            switch(b) {
4196
            default:
4197
            case 0x80:
4198
            case 0x81:
4199
            case 0x82:
4200
                val = insn_get(s, ot);
4201
                break;
4202
            case 0x83:
4203
                val = (int8_t)insn_get(s, OT_BYTE);
4204
                break;
4205
            }
4206
            gen_op_movl_T1_im(val);
4207
            gen_op(s, op, ot, opreg);
4208
        }
4209
        break;
4210

    
4211
        /**************************/
4212
        /* inc, dec, and other misc arith */
4213
    case 0x40 ... 0x47: /* inc Gv */
4214
        ot = dflag ? OT_LONG : OT_WORD;
4215
        gen_inc(s, ot, OR_EAX + (b & 7), 1);
4216
        break;
4217
    case 0x48 ... 0x4f: /* dec Gv */
4218
        ot = dflag ? OT_LONG : OT_WORD;
4219
        gen_inc(s, ot, OR_EAX + (b & 7), -1);
4220
        break;
4221
    case 0xf6: /* GRP3 */
4222
    case 0xf7:
4223
        if ((b & 1) == 0)
4224
            ot = OT_BYTE;
4225
        else
4226
            ot = dflag + OT_WORD;
4227

    
4228
        modrm = ldub_code(s->pc++);
4229
        mod = (modrm >> 6) & 3;
4230
        rm = (modrm & 7) | REX_B(s);
4231
        op = (modrm >> 3) & 7;
4232
        if (mod != 3) {
4233
            if (op == 0)
4234
                s->rip_offset = insn_const_size(ot);
4235
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4236
            gen_op_ld_T0_A0(ot + s->mem_index);
4237
        } else {
4238
            gen_op_mov_TN_reg(ot, 0, rm);
4239
        }
4240

    
4241
        switch(op) {
4242
        case 0: /* test */
4243
            val = insn_get(s, ot);
4244
            gen_op_movl_T1_im(val);
4245
            gen_op_testl_T0_T1_cc();
4246
            s->cc_op = CC_OP_LOGICB + ot;
4247
            break;
4248
        case 2: /* not */
4249
            tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
4250
            if (mod != 3) {
4251
                gen_op_st_T0_A0(ot + s->mem_index);
4252
            } else {
4253
                gen_op_mov_reg_T0(ot, rm);
4254
            }
4255
            break;
4256
        case 3: /* neg */
4257
            tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
4258
            if (mod != 3) {
4259
                gen_op_st_T0_A0(ot + s->mem_index);
4260
            } else {
4261
                gen_op_mov_reg_T0(ot, rm);
4262
            }
4263
            gen_op_update_neg_cc();
4264
            s->cc_op = CC_OP_SUBB + ot;
4265
            break;
4266
        case 4: /* mul */
4267
            switch(ot) {
4268
            case OT_BYTE:
4269
                gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX);
4270
                tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
4271
                tcg_gen_ext8u_tl(cpu_T[1], cpu_T[1]);
4272
                /* XXX: use 32 bit mul which could be faster */
4273
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4274
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
4275
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4276
                tcg_gen_andi_tl(cpu_cc_src, cpu_T[0], 0xff00);
4277
                s->cc_op = CC_OP_MULB;
4278
                break;
4279
            case OT_WORD:
4280
                gen_op_mov_TN_reg(OT_WORD, 1, R_EAX);
4281
                tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
4282
                tcg_gen_ext16u_tl(cpu_T[1], cpu_T[1]);
4283
                /* XXX: use 32 bit mul which could be faster */
4284
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4285
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
4286
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4287
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
4288
                gen_op_mov_reg_T0(OT_WORD, R_EDX);
4289
                tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4290
                s->cc_op = CC_OP_MULW;
4291
                break;
4292
            default:
4293
            case OT_LONG:
4294
#ifdef TARGET_X86_64
4295
                gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4296
                tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
4297
                tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
4298
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4299
                gen_op_mov_reg_T0(OT_LONG, R_EAX);
4300
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4301
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
4302
                gen_op_mov_reg_T0(OT_LONG, R_EDX);
4303
                tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4304
#else
4305
                {
4306
                    TCGv_i64 t0, t1;
4307
                    t0 = tcg_temp_new_i64();
4308
                    t1 = tcg_temp_new_i64();
4309
                    gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4310
                    tcg_gen_extu_i32_i64(t0, cpu_T[0]);
4311
                    tcg_gen_extu_i32_i64(t1, cpu_T[1]);
4312
                    tcg_gen_mul_i64(t0, t0, t1);
4313
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4314
                    gen_op_mov_reg_T0(OT_LONG, R_EAX);
4315
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4316
                    tcg_gen_shri_i64(t0, t0, 32);
4317
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4318
                    gen_op_mov_reg_T0(OT_LONG, R_EDX);
4319
                    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4320
                }
4321
#endif
4322
                s->cc_op = CC_OP_MULL;
4323
                break;
4324
#ifdef TARGET_X86_64
4325
            case OT_QUAD:
4326
                gen_helper_mulq_EAX_T0(cpu_T[0]);
4327
                s->cc_op = CC_OP_MULQ;
4328
                break;
4329
#endif
4330
            }
4331
            break;
4332
        case 5: /* imul */
4333
            switch(ot) {
4334
            case OT_BYTE:
4335
                gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX);
4336
                tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
4337
                tcg_gen_ext8s_tl(cpu_T[1], cpu_T[1]);
4338
                /* XXX: use 32 bit mul which could be faster */
4339
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4340
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
4341
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4342
                tcg_gen_ext8s_tl(cpu_tmp0, cpu_T[0]);
4343
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4344
                s->cc_op = CC_OP_MULB;
4345
                break;
4346
            case OT_WORD:
4347
                gen_op_mov_TN_reg(OT_WORD, 1, R_EAX);
4348
                tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4349
                tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
4350
                /* XXX: use 32 bit mul which could be faster */
4351
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4352
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
4353
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4354
                tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
4355
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4356
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
4357
                gen_op_mov_reg_T0(OT_WORD, R_EDX);
4358
                s->cc_op = CC_OP_MULW;
4359
                break;
4360
            default:
4361
            case OT_LONG:
4362
#ifdef TARGET_X86_64
4363
                gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4364
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4365
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
4366
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4367
                gen_op_mov_reg_T0(OT_LONG, R_EAX);
4368
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4369
                tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
4370
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4371
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
4372
                gen_op_mov_reg_T0(OT_LONG, R_EDX);
4373
#else
4374
                {
4375
                    TCGv_i64 t0, t1;
4376
                    t0 = tcg_temp_new_i64();
4377
                    t1 = tcg_temp_new_i64();
4378
                    gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4379
                    tcg_gen_ext_i32_i64(t0, cpu_T[0]);
4380
                    tcg_gen_ext_i32_i64(t1, cpu_T[1]);
4381
                    tcg_gen_mul_i64(t0, t0, t1);
4382
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4383
                    gen_op_mov_reg_T0(OT_LONG, R_EAX);
4384
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4385
                    tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
4386
                    tcg_gen_shri_i64(t0, t0, 32);
4387
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4388
                    gen_op_mov_reg_T0(OT_LONG, R_EDX);
4389
                    tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4390
                }
4391
#endif
4392
                s->cc_op = CC_OP_MULL;
4393
                break;
4394
#ifdef TARGET_X86_64
4395
            case OT_QUAD:
4396
                gen_helper_imulq_EAX_T0(cpu_T[0]);
4397
                s->cc_op = CC_OP_MULQ;
4398
                break;
4399
#endif
4400
            }
4401
            break;
4402
        case 6: /* div */
4403
            switch(ot) {
4404
            case OT_BYTE:
4405
                gen_jmp_im(pc_start - s->cs_base);
4406
                gen_helper_divb_AL(cpu_T[0]);
4407
                break;
4408
            case OT_WORD:
4409
                gen_jmp_im(pc_start - s->cs_base);
4410
                gen_helper_divw_AX(cpu_T[0]);
4411
                break;
4412
            default:
4413
            case OT_LONG:
4414
                gen_jmp_im(pc_start - s->cs_base);
4415
                gen_helper_divl_EAX(cpu_T[0]);
4416
                break;
4417
#ifdef TARGET_X86_64
4418
            case OT_QUAD:
4419
                gen_jmp_im(pc_start - s->cs_base);
4420
                gen_helper_divq_EAX(cpu_T[0]);
4421
                break;
4422
#endif
4423
            }
4424
            break;
4425
        case 7: /* idiv */
4426
            switch(ot) {
4427
            case OT_BYTE:
4428
                gen_jmp_im(pc_start - s->cs_base);
4429
                gen_helper_idivb_AL(cpu_T[0]);
4430
                break;
4431
            case OT_WORD:
4432
                gen_jmp_im(pc_start - s->cs_base);
4433
                gen_helper_idivw_AX(cpu_T[0]);
4434
                break;
4435
            default:
4436
            case OT_LONG:
4437
                gen_jmp_im(pc_start - s->cs_base);
4438
                gen_helper_idivl_EAX(cpu_T[0]);
4439
                break;
4440
#ifdef TARGET_X86_64
4441
            case OT_QUAD:
4442
                gen_jmp_im(pc_start - s->cs_base);
4443
                gen_helper_idivq_EAX(cpu_T[0]);
4444
                break;
4445
#endif
4446
            }
4447
            break;
4448
        default:
4449
            goto illegal_op;
4450
        }
4451
        break;
4452

    
4453
    case 0xfe: /* GRP4 */
4454
    case 0xff: /* GRP5 */
4455
        if ((b & 1) == 0)
4456
            ot = OT_BYTE;
4457
        else
4458
            ot = dflag + OT_WORD;
4459

    
4460
        modrm = ldub_code(s->pc++);
4461
        mod = (modrm >> 6) & 3;
4462
        rm = (modrm & 7) | REX_B(s);
4463
        op = (modrm >> 3) & 7;
4464
        if (op >= 2 && b == 0xfe) {
4465
            goto illegal_op;
4466
        }
4467
        if (CODE64(s)) {
4468
            if (op == 2 || op == 4) {
4469
                /* operand size for jumps is 64 bit */
4470
                ot = OT_QUAD;
4471
            } else if (op == 3 || op == 5) {
4472
                /* for call calls, the operand is 16 or 32 bit, even
4473
                   in long mode */
4474
                ot = dflag ? OT_LONG : OT_WORD;
4475
            } else if (op == 6) {
4476
                /* default push size is 64 bit */
4477
                ot = dflag ? OT_QUAD : OT_WORD;
4478
            }
4479
        }
4480
        if (mod != 3) {
4481
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4482
            if (op >= 2 && op != 3 && op != 5)
4483
                gen_op_ld_T0_A0(ot + s->mem_index);
4484
        } else {
4485
            gen_op_mov_TN_reg(ot, 0, rm);
4486
        }
4487

    
4488
        switch(op) {
4489
        case 0: /* inc Ev */
4490
            if (mod != 3)
4491
                opreg = OR_TMP0;
4492
            else
4493
                opreg = rm;
4494
            gen_inc(s, ot, opreg, 1);
4495
            break;
4496
        case 1: /* dec Ev */
4497
            if (mod != 3)
4498
                opreg = OR_TMP0;
4499
            else
4500
                opreg = rm;
4501
            gen_inc(s, ot, opreg, -1);
4502
            break;
4503
        case 2: /* call Ev */
4504
            /* XXX: optimize if memory (no 'and' is necessary) */
4505
            if (s->dflag == 0)
4506
                gen_op_andl_T0_ffff();
4507
            next_eip = s->pc - s->cs_base;
4508
            gen_movtl_T1_im(next_eip);
4509
            gen_push_T1(s);
4510
            gen_op_jmp_T0();
4511
            gen_eob(s);
4512
            break;
4513
        case 3: /* lcall Ev */
4514
            gen_op_ld_T1_A0(ot + s->mem_index);
4515
            gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4516
            gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
4517
        do_lcall:
4518
            if (s->pe && !s->vm86) {
4519
                if (s->cc_op != CC_OP_DYNAMIC)
4520
                    gen_op_set_cc_op(s->cc_op);
4521
                gen_jmp_im(pc_start - s->cs_base);
4522
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4523
                gen_helper_lcall_protected(cpu_tmp2_i32, cpu_T[1],
4524
                                           tcg_const_i32(dflag), 
4525
                                           tcg_const_i32(s->pc - pc_start));
4526
            } else {
4527
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4528
                gen_helper_lcall_real(cpu_tmp2_i32, cpu_T[1],
4529
                                      tcg_const_i32(dflag), 
4530
                                      tcg_const_i32(s->pc - s->cs_base));
4531
            }
4532
            gen_eob(s);
4533
            break;
4534
        case 4: /* jmp Ev */
4535
            if (s->dflag == 0)
4536
                gen_op_andl_T0_ffff();
4537
            gen_op_jmp_T0();
4538
            gen_eob(s);
4539
            break;
4540
        case 5: /* ljmp Ev */
4541
            gen_op_ld_T1_A0(ot + s->mem_index);
4542
            gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4543
            gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
4544
        do_ljmp:
4545
            if (s->pe && !s->vm86) {
4546
                if (s->cc_op != CC_OP_DYNAMIC)
4547
                    gen_op_set_cc_op(s->cc_op);
4548
                gen_jmp_im(pc_start - s->cs_base);
4549
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4550
                gen_helper_ljmp_protected(cpu_tmp2_i32, cpu_T[1],
4551
                                          tcg_const_i32(s->pc - pc_start));
4552
            } else {
4553
                gen_op_movl_seg_T0_vm(R_CS);
4554
                gen_op_movl_T0_T1();
4555
                gen_op_jmp_T0();
4556
            }
4557
            gen_eob(s);
4558
            break;
4559
        case 6: /* push Ev */
4560
            gen_push_T0(s);
4561
            break;
4562
        default:
4563
            goto illegal_op;
4564
        }
4565
        break;
4566

    
4567
    case 0x84: /* test Ev, Gv */
4568
    case 0x85:
4569
        if ((b & 1) == 0)
4570
            ot = OT_BYTE;
4571
        else
4572
            ot = dflag + OT_WORD;
4573

    
4574
        modrm = ldub_code(s->pc++);
4575
        mod = (modrm >> 6) & 3;
4576
        rm = (modrm & 7) | REX_B(s);
4577
        reg = ((modrm >> 3) & 7) | rex_r;
4578

    
4579
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
4580
        gen_op_mov_TN_reg(ot, 1, reg);
4581
        gen_op_testl_T0_T1_cc();
4582
        s->cc_op = CC_OP_LOGICB + ot;
4583
        break;
4584

    
4585
    case 0xa8: /* test eAX, Iv */
4586
    case 0xa9:
4587
        if ((b & 1) == 0)
4588
            ot = OT_BYTE;
4589
        else
4590
            ot = dflag + OT_WORD;
4591
        val = insn_get(s, ot);
4592

    
4593
        gen_op_mov_TN_reg(ot, 0, OR_EAX);
4594
        gen_op_movl_T1_im(val);
4595
        gen_op_testl_T0_T1_cc();
4596
        s->cc_op = CC_OP_LOGICB + ot;
4597
        break;
4598

    
4599
    case 0x98: /* CWDE/CBW */
4600
#ifdef TARGET_X86_64
4601
        if (dflag == 2) {
4602
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
4603
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4604
            gen_op_mov_reg_T0(OT_QUAD, R_EAX);
4605
        } else
4606
#endif
4607
        if (dflag == 1) {
4608
            gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
4609
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4610
            gen_op_mov_reg_T0(OT_LONG, R_EAX);
4611
        } else {
4612
            gen_op_mov_TN_reg(OT_BYTE, 0, R_EAX);
4613
            tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
4614
            gen_op_mov_reg_T0(OT_WORD, R_EAX);
4615
        }
4616
        break;
4617
    case 0x99: /* CDQ/CWD */
4618
#ifdef TARGET_X86_64
4619
        if (dflag == 2) {
4620
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
4621
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 63);
4622
            gen_op_mov_reg_T0(OT_QUAD, R_EDX);
4623
        } else
4624
#endif
4625
        if (dflag == 1) {
4626
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
4627
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4628
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 31);
4629
            gen_op_mov_reg_T0(OT_LONG, R_EDX);
4630
        } else {
4631
            gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
4632
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4633
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 15);
4634
            gen_op_mov_reg_T0(OT_WORD, R_EDX);
4635
        }
4636
        break;
4637
    case 0x1af: /* imul Gv, Ev */
4638
    case 0x69: /* imul Gv, Ev, I */
4639
    case 0x6b:
4640
        ot = dflag + OT_WORD;
4641
        modrm = ldub_code(s->pc++);
4642
        reg = ((modrm >> 3) & 7) | rex_r;
4643
        if (b == 0x69)
4644
            s->rip_offset = insn_const_size(ot);
4645
        else if (b == 0x6b)
4646
            s->rip_offset = 1;
4647
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
4648
        if (b == 0x69) {
4649
            val = insn_get(s, ot);
4650
            gen_op_movl_T1_im(val);
4651
        } else if (b == 0x6b) {
4652
            val = (int8_t)insn_get(s, OT_BYTE);
4653
            gen_op_movl_T1_im(val);
4654
        } else {
4655
            gen_op_mov_TN_reg(ot, 1, reg);
4656
        }
4657

    
4658
#ifdef TARGET_X86_64
4659
        if (ot == OT_QUAD) {
4660
            gen_helper_imulq_T0_T1(cpu_T[0], cpu_T[0], cpu_T[1]);
4661
        } else
4662
#endif
4663
        if (ot == OT_LONG) {
4664
#ifdef TARGET_X86_64
4665
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4666
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
4667
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4668
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4669
                tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
4670
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4671
#else
4672
                {
4673
                    TCGv_i64 t0, t1;
4674
                    t0 = tcg_temp_new_i64();
4675
                    t1 = tcg_temp_new_i64();
4676
                    tcg_gen_ext_i32_i64(t0, cpu_T[0]);
4677
                    tcg_gen_ext_i32_i64(t1, cpu_T[1]);
4678
                    tcg_gen_mul_i64(t0, t0, t1);
4679
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4680
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4681
                    tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
4682
                    tcg_gen_shri_i64(t0, t0, 32);
4683
                    tcg_gen_trunc_i64_i32(cpu_T[1], t0);
4684
                    tcg_gen_sub_tl(cpu_cc_src, cpu_T[1], cpu_tmp0);
4685
                }
4686
#endif
4687
        } else {
4688
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4689
            tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
4690
            /* XXX: use 32 bit mul which could be faster */
4691
            tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4692
            tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4693
            tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
4694
            tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4695
        }
4696
        gen_op_mov_reg_T0(ot, reg);
4697
        s->cc_op = CC_OP_MULB + ot;
4698
        break;
4699
    case 0x1c0:
4700
    case 0x1c1: /* xadd Ev, Gv */
4701
        if ((b & 1) == 0)
4702
            ot = OT_BYTE;
4703
        else
4704
            ot = dflag + OT_WORD;
4705
        modrm = ldub_code(s->pc++);
4706
        reg = ((modrm >> 3) & 7) | rex_r;
4707
        mod = (modrm >> 6) & 3;
4708
        if (mod == 3) {
4709
            rm = (modrm & 7) | REX_B(s);
4710
            gen_op_mov_TN_reg(ot, 0, reg);
4711
            gen_op_mov_TN_reg(ot, 1, rm);
4712
            gen_op_addl_T0_T1();
4713
            gen_op_mov_reg_T1(ot, reg);
4714
            gen_op_mov_reg_T0(ot, rm);
4715
        } else {
4716
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4717
            gen_op_mov_TN_reg(ot, 0, reg);
4718
            gen_op_ld_T1_A0(ot + s->mem_index);
4719
            gen_op_addl_T0_T1();
4720
            gen_op_st_T0_A0(ot + s->mem_index);
4721
            gen_op_mov_reg_T1(ot, reg);
4722
        }
4723
        gen_op_update2_cc();
4724
        s->cc_op = CC_OP_ADDB + ot;
4725
        break;
4726
    case 0x1b0:
4727
    case 0x1b1: /* cmpxchg Ev, Gv */
4728
        {
4729
            int label1, label2;
4730
            TCGv t0, t1, t2, a0;
4731

    
4732
            if ((b & 1) == 0)
4733
                ot = OT_BYTE;
4734
            else
4735
                ot = dflag + OT_WORD;
4736
            modrm = ldub_code(s->pc++);
4737
            reg = ((modrm >> 3) & 7) | rex_r;
4738
            mod = (modrm >> 6) & 3;
4739
            t0 = tcg_temp_local_new();
4740
            t1 = tcg_temp_local_new();
4741
            t2 = tcg_temp_local_new();
4742
            a0 = tcg_temp_local_new();
4743
            gen_op_mov_v_reg(ot, t1, reg);
4744
            if (mod == 3) {
4745
                rm = (modrm & 7) | REX_B(s);
4746
                gen_op_mov_v_reg(ot, t0, rm);
4747
            } else {
4748
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4749
                tcg_gen_mov_tl(a0, cpu_A0);
4750
                gen_op_ld_v(ot + s->mem_index, t0, a0);
4751
                rm = 0; /* avoid warning */
4752
            }
4753
            label1 = gen_new_label();
4754
            tcg_gen_ld_tl(t2, cpu_env, offsetof(CPUState, regs[R_EAX]));
4755
            tcg_gen_sub_tl(t2, t2, t0);
4756
            gen_extu(ot, t2);
4757
            tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
4758
            if (mod == 3) {
4759
                label2 = gen_new_label();
4760
                gen_op_mov_reg_v(ot, R_EAX, t0);
4761
                tcg_gen_br(label2);
4762
                gen_set_label(label1);
4763
                gen_op_mov_reg_v(ot, rm, t1);
4764
                gen_set_label(label2);
4765
            } else {
4766
                tcg_gen_mov_tl(t1, t0);
4767
                gen_op_mov_reg_v(ot, R_EAX, t0);
4768
                gen_set_label(label1);
4769
                /* always store */
4770
                gen_op_st_v(ot + s->mem_index, t1, a0);
4771
            }
4772
            tcg_gen_mov_tl(cpu_cc_src, t0);
4773
            tcg_gen_mov_tl(cpu_cc_dst, t2);
4774
            s->cc_op = CC_OP_SUBB + ot;
4775
            tcg_temp_free(t0);
4776
            tcg_temp_free(t1);
4777
            tcg_temp_free(t2);
4778
            tcg_temp_free(a0);
4779
        }
4780
        break;
4781
    case 0x1c7: /* cmpxchg8b */
4782
        modrm = ldub_code(s->pc++);
4783
        mod = (modrm >> 6) & 3;
4784
        if ((mod == 3) || ((modrm & 0x38) != 0x8))
4785
            goto illegal_op;
4786
#ifdef TARGET_X86_64
4787
        if (dflag == 2) {
4788
            if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
4789
                goto illegal_op;
4790
            gen_jmp_im(pc_start - s->cs_base);
4791
            if (s->cc_op != CC_OP_DYNAMIC)
4792
                gen_op_set_cc_op(s->cc_op);
4793
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4794
            gen_helper_cmpxchg16b(cpu_A0);
4795
        } else
4796
#endif        
4797
        {
4798
            if (!(s->cpuid_features & CPUID_CX8))
4799
                goto illegal_op;
4800
            gen_jmp_im(pc_start - s->cs_base);
4801
            if (s->cc_op != CC_OP_DYNAMIC)
4802
                gen_op_set_cc_op(s->cc_op);
4803
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4804
            gen_helper_cmpxchg8b(cpu_A0);
4805
        }
4806
        s->cc_op = CC_OP_EFLAGS;
4807
        break;
4808

    
4809
        /**************************/
4810
        /* push/pop */
4811
    case 0x50 ... 0x57: /* push */
4812
        gen_op_mov_TN_reg(OT_LONG, 0, (b & 7) | REX_B(s));
4813
        gen_push_T0(s);
4814
        break;
4815
    case 0x58 ... 0x5f: /* pop */
4816
        if (CODE64(s)) {
4817
            ot = dflag ? OT_QUAD : OT_WORD;
4818
        } else {
4819
            ot = dflag + OT_WORD;
4820
        }
4821
        gen_pop_T0(s);
4822
        /* NOTE: order is important for pop %sp */
4823
        gen_pop_update(s);
4824
        gen_op_mov_reg_T0(ot, (b & 7) | REX_B(s));
4825
        break;
4826
    case 0x60: /* pusha */
4827
        if (CODE64(s))
4828
            goto illegal_op;
4829
        gen_pusha(s);
4830
        break;
4831
    case 0x61: /* popa */
4832
        if (CODE64(s))
4833
            goto illegal_op;
4834
        gen_popa(s);
4835
        break;
4836
    case 0x68: /* push Iv */
4837
    case 0x6a:
4838
        if (CODE64(s)) {
4839
            ot = dflag ? OT_QUAD : OT_WORD;
4840
        } else {
4841
            ot = dflag + OT_WORD;
4842
        }
4843
        if (b == 0x68)
4844
            val = insn_get(s, ot);
4845
        else
4846
            val = (int8_t)insn_get(s, OT_BYTE);
4847
        gen_op_movl_T0_im(val);
4848
        gen_push_T0(s);
4849
        break;
4850
    case 0x8f: /* pop Ev */
4851
        if (CODE64(s)) {
4852
            ot = dflag ? OT_QUAD : OT_WORD;
4853
        } else {
4854
            ot = dflag + OT_WORD;
4855
        }
4856
        modrm = ldub_code(s->pc++);
4857
        mod = (modrm >> 6) & 3;
4858
        gen_pop_T0(s);
4859
        if (mod == 3) {
4860
            /* NOTE: order is important for pop %sp */
4861
            gen_pop_update(s);
4862
            rm = (modrm & 7) | REX_B(s);
4863
            gen_op_mov_reg_T0(ot, rm);
4864
        } else {
4865
            /* NOTE: order is important too for MMU exceptions */
4866
            s->popl_esp_hack = 1 << ot;
4867
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
4868
            s->popl_esp_hack = 0;
4869
            gen_pop_update(s);
4870
        }
4871
        break;
4872
    case 0xc8: /* enter */
4873
        {
4874
            int level;
4875
            val = lduw_code(s->pc);
4876
            s->pc += 2;
4877
            level = ldub_code(s->pc++);
4878
            gen_enter(s, val, level);
4879
        }
4880
        break;
4881
    case 0xc9: /* leave */
4882
        /* XXX: exception not precise (ESP is updated before potential exception) */
4883
        if (CODE64(s)) {
4884
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EBP);
4885
            gen_op_mov_reg_T0(OT_QUAD, R_ESP);
4886
        } else if (s->ss32) {
4887
            gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
4888
            gen_op_mov_reg_T0(OT_LONG, R_ESP);
4889
        } else {
4890
            gen_op_mov_TN_reg(OT_WORD, 0, R_EBP);
4891
            gen_op_mov_reg_T0(OT_WORD, R_ESP);
4892
        }
4893
        gen_pop_T0(s);
4894
        if (CODE64(s)) {
4895
            ot = dflag ? OT_QUAD : OT_WORD;
4896
        } else {
4897
            ot = dflag + OT_WORD;
4898
        }
4899
        gen_op_mov_reg_T0(ot, R_EBP);
4900
        gen_pop_update(s);
4901
        break;
4902
    case 0x06: /* push es */
4903
    case 0x0e: /* push cs */
4904
    case 0x16: /* push ss */
4905
    case 0x1e: /* push ds */
4906
        if (CODE64(s))
4907
            goto illegal_op;
4908
        gen_op_movl_T0_seg(b >> 3);
4909
        gen_push_T0(s);
4910
        break;
4911
    case 0x1a0: /* push fs */
4912
    case 0x1a8: /* push gs */
4913
        gen_op_movl_T0_seg((b >> 3) & 7);
4914
        gen_push_T0(s);
4915
        break;
4916
    case 0x07: /* pop es */
4917
    case 0x17: /* pop ss */
4918
    case 0x1f: /* pop ds */
4919
        if (CODE64(s))
4920
            goto illegal_op;
4921
        reg = b >> 3;
4922
        gen_pop_T0(s);
4923
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
4924
        gen_pop_update(s);
4925
        if (reg == R_SS) {
4926
            /* if reg == SS, inhibit interrupts/trace. */
4927
            /* If several instructions disable interrupts, only the
4928
               _first_ does it */
4929
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
4930
                gen_helper_set_inhibit_irq();
4931
            s->tf = 0;
4932
        }
4933
        if (s->is_jmp) {
4934
            gen_jmp_im(s->pc - s->cs_base);
4935
            gen_eob(s);
4936
        }
4937
        break;
4938
    case 0x1a1: /* pop fs */
4939
    case 0x1a9: /* pop gs */
4940
        gen_pop_T0(s);
4941
        gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
4942
        gen_pop_update(s);
4943
        if (s->is_jmp) {
4944
            gen_jmp_im(s->pc - s->cs_base);
4945
            gen_eob(s);
4946
        }
4947
        break;
4948

    
4949
        /**************************/
4950
        /* mov */
4951
    case 0x88:
4952
    case 0x89: /* mov Gv, Ev */
4953
        if ((b & 1) == 0)
4954
            ot = OT_BYTE;
4955
        else
4956
            ot = dflag + OT_WORD;
4957
        modrm = ldub_code(s->pc++);
4958
        reg = ((modrm >> 3) & 7) | rex_r;
4959

    
4960
        /* generate a generic store */
4961
        gen_ldst_modrm(s, modrm, ot, reg, 1);
4962
        break;
4963
    case 0xc6:
4964
    case 0xc7: /* mov Ev, Iv */
4965
        if ((b & 1) == 0)
4966
            ot = OT_BYTE;
4967
        else
4968
            ot = dflag + OT_WORD;
4969
        modrm = ldub_code(s->pc++);
4970
        mod = (modrm >> 6) & 3;
4971
        if (mod != 3) {
4972
            s->rip_offset = insn_const_size(ot);
4973
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4974
        }
4975
        val = insn_get(s, ot);
4976
        gen_op_movl_T0_im(val);
4977
        if (mod != 3)
4978
            gen_op_st_T0_A0(ot + s->mem_index);
4979
        else
4980
            gen_op_mov_reg_T0(ot, (modrm & 7) | REX_B(s));
4981
        break;
4982
    case 0x8a:
4983
    case 0x8b: /* mov Ev, Gv */
4984
        if ((b & 1) == 0)
4985
            ot = OT_BYTE;
4986
        else
4987
            ot = OT_WORD + dflag;
4988
        modrm = ldub_code(s->pc++);
4989
        reg = ((modrm >> 3) & 7) | rex_r;
4990

    
4991
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
4992
        gen_op_mov_reg_T0(ot, reg);
4993
        break;
4994
    case 0x8e: /* mov seg, Gv */
4995
        modrm = ldub_code(s->pc++);
4996
        reg = (modrm >> 3) & 7;
4997
        if (reg >= 6 || reg == R_CS)
4998
            goto illegal_op;
4999
        gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
5000
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
5001
        if (reg == R_SS) {
5002
            /* if reg == SS, inhibit interrupts/trace */
5003
            /* If several instructions disable interrupts, only the
5004
               _first_ does it */
5005
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
5006
                gen_helper_set_inhibit_irq();
5007
            s->tf = 0;
5008
        }
5009
        if (s->is_jmp) {
5010
            gen_jmp_im(s->pc - s->cs_base);
5011
            gen_eob(s);
5012
        }
5013
        break;
5014
    case 0x8c: /* mov Gv, seg */
5015
        modrm = ldub_code(s->pc++);
5016
        reg = (modrm >> 3) & 7;
5017
        mod = (modrm >> 6) & 3;
5018
        if (reg >= 6)
5019
            goto illegal_op;
5020
        gen_op_movl_T0_seg(reg);
5021
        if (mod == 3)
5022
            ot = OT_WORD + dflag;
5023
        else
5024
            ot = OT_WORD;
5025
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
5026
        break;
5027

    
5028
    case 0x1b6: /* movzbS Gv, Eb */
5029
    case 0x1b7: /* movzwS Gv, Eb */
5030
    case 0x1be: /* movsbS Gv, Eb */
5031
    case 0x1bf: /* movswS Gv, Eb */
5032
        {
5033
            int d_ot;
5034
            /* d_ot is the size of destination */
5035
            d_ot = dflag + OT_WORD;
5036
            /* ot is the size of source */
5037
            ot = (b & 1) + OT_BYTE;
5038
            modrm = ldub_code(s->pc++);
5039
            reg = ((modrm >> 3) & 7) | rex_r;
5040
            mod = (modrm >> 6) & 3;
5041
            rm = (modrm & 7) | REX_B(s);
5042

    
5043
            if (mod == 3) {
5044
                gen_op_mov_TN_reg(ot, 0, rm);
5045
                switch(ot | (b & 8)) {
5046
                case OT_BYTE:
5047
                    tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
5048
                    break;
5049
                case OT_BYTE | 8:
5050
                    tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
5051
                    break;
5052
                case OT_WORD:
5053
                    tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
5054
                    break;
5055
                default:
5056
                case OT_WORD | 8:
5057
                    tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
5058
                    break;
5059
                }
5060
                gen_op_mov_reg_T0(d_ot, reg);
5061
            } else {
5062
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5063
                if (b & 8) {
5064
                    gen_op_lds_T0_A0(ot + s->mem_index);
5065
                } else {
5066
                    gen_op_ldu_T0_A0(ot + s->mem_index);
5067
                }
5068
                gen_op_mov_reg_T0(d_ot, reg);
5069
            }
5070
        }
5071
        break;
5072

    
5073
    case 0x8d: /* lea */
5074
        ot = dflag + OT_WORD;
5075
        modrm = ldub_code(s->pc++);
5076
        mod = (modrm >> 6) & 3;
5077
        if (mod == 3)
5078
            goto illegal_op;
5079
        reg = ((modrm >> 3) & 7) | rex_r;
5080
        /* we must ensure that no segment is added */
5081
        s->override = -1;
5082
        val = s->addseg;
5083
        s->addseg = 0;
5084
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5085
        s->addseg = val;
5086
        gen_op_mov_reg_A0(ot - OT_WORD, reg);
5087
        break;
5088

    
5089
    case 0xa0: /* mov EAX, Ov */
5090
    case 0xa1:
5091
    case 0xa2: /* mov Ov, EAX */
5092
    case 0xa3:
5093
        {
5094
            target_ulong offset_addr;
5095

    
5096
            if ((b & 1) == 0)
5097
                ot = OT_BYTE;
5098
            else
5099
                ot = dflag + OT_WORD;
5100
#ifdef TARGET_X86_64
5101
            if (s->aflag == 2) {
5102
                offset_addr = ldq_code(s->pc);
5103
                s->pc += 8;
5104
                gen_op_movq_A0_im(offset_addr);
5105
            } else
5106
#endif
5107
            {
5108
                if (s->aflag) {
5109
                    offset_addr = insn_get(s, OT_LONG);
5110
                } else {
5111
                    offset_addr = insn_get(s, OT_WORD);
5112
                }
5113
                gen_op_movl_A0_im(offset_addr);
5114
            }
5115
            gen_add_A0_ds_seg(s);
5116
            if ((b & 2) == 0) {
5117
                gen_op_ld_T0_A0(ot + s->mem_index);
5118
                gen_op_mov_reg_T0(ot, R_EAX);
5119
            } else {
5120
                gen_op_mov_TN_reg(ot, 0, R_EAX);
5121
                gen_op_st_T0_A0(ot + s->mem_index);
5122
            }
5123
        }
5124
        break;
5125
    case 0xd7: /* xlat */
5126
#ifdef TARGET_X86_64
5127
        if (s->aflag == 2) {
5128
            gen_op_movq_A0_reg(R_EBX);
5129
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
5130
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
5131
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
5132
        } else
5133
#endif
5134
        {
5135
            gen_op_movl_A0_reg(R_EBX);
5136
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
5137
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
5138
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
5139
            if (s->aflag == 0)
5140
                gen_op_andl_A0_ffff();
5141
            else
5142
                tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
5143
        }
5144
        gen_add_A0_ds_seg(s);
5145
        gen_op_ldu_T0_A0(OT_BYTE + s->mem_index);
5146
        gen_op_mov_reg_T0(OT_BYTE, R_EAX);
5147
        break;
5148
    case 0xb0 ... 0xb7: /* mov R, Ib */
5149
        val = insn_get(s, OT_BYTE);
5150
        gen_op_movl_T0_im(val);
5151
        gen_op_mov_reg_T0(OT_BYTE, (b & 7) | REX_B(s));
5152
        break;
5153
    case 0xb8 ... 0xbf: /* mov R, Iv */
5154
#ifdef TARGET_X86_64
5155
        if (dflag == 2) {
5156
            uint64_t tmp;
5157
            /* 64 bit case */
5158
            tmp = ldq_code(s->pc);
5159
            s->pc += 8;
5160
            reg = (b & 7) | REX_B(s);
5161
            gen_movtl_T0_im(tmp);
5162
            gen_op_mov_reg_T0(OT_QUAD, reg);
5163
        } else
5164
#endif
5165
        {
5166
            ot = dflag ? OT_LONG : OT_WORD;
5167
            val = insn_get(s, ot);
5168
            reg = (b & 7) | REX_B(s);
5169
            gen_op_movl_T0_im(val);
5170
            gen_op_mov_reg_T0(ot, reg);
5171
        }
5172
        break;
5173

    
5174
    case 0x91 ... 0x97: /* xchg R, EAX */
5175
        ot = dflag + OT_WORD;
5176
        reg = (b & 7) | REX_B(s);
5177
        rm = R_EAX;
5178
        goto do_xchg_reg;
5179
    case 0x86:
5180
    case 0x87: /* xchg Ev, Gv */
5181
        if ((b & 1) == 0)
5182
            ot = OT_BYTE;
5183
        else
5184
            ot = dflag + OT_WORD;
5185
        modrm = ldub_code(s->pc++);
5186
        reg = ((modrm >> 3) & 7) | rex_r;
5187
        mod = (modrm >> 6) & 3;
5188
        if (mod == 3) {
5189
            rm = (modrm & 7) | REX_B(s);
5190
        do_xchg_reg:
5191
            gen_op_mov_TN_reg(ot, 0, reg);
5192
            gen_op_mov_TN_reg(ot, 1, rm);
5193
            gen_op_mov_reg_T0(ot, rm);
5194
            gen_op_mov_reg_T1(ot, reg);
5195
        } else {
5196
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5197
            gen_op_mov_TN_reg(ot, 0, reg);
5198
            /* for xchg, lock is implicit */
5199
            if (!(prefixes & PREFIX_LOCK))
5200
                gen_helper_lock();
5201
            gen_op_ld_T1_A0(ot + s->mem_index);
5202
            gen_op_st_T0_A0(ot + s->mem_index);
5203
            if (!(prefixes & PREFIX_LOCK))
5204
                gen_helper_unlock();
5205
            gen_op_mov_reg_T1(ot, reg);
5206
        }
5207
        break;
5208
    case 0xc4: /* les Gv */
5209
        if (CODE64(s))
5210
            goto illegal_op;
5211
        op = R_ES;
5212
        goto do_lxx;
5213
    case 0xc5: /* lds Gv */
5214
        if (CODE64(s))
5215
            goto illegal_op;
5216
        op = R_DS;
5217
        goto do_lxx;
5218
    case 0x1b2: /* lss Gv */
5219
        op = R_SS;
5220
        goto do_lxx;
5221
    case 0x1b4: /* lfs Gv */
5222
        op = R_FS;
5223
        goto do_lxx;
5224
    case 0x1b5: /* lgs Gv */
5225
        op = R_GS;
5226
    do_lxx:
5227
        ot = dflag ? OT_LONG : OT_WORD;
5228
        modrm = ldub_code(s->pc++);
5229
        reg = ((modrm >> 3) & 7) | rex_r;
5230
        mod = (modrm >> 6) & 3;
5231
        if (mod == 3)
5232
            goto illegal_op;
5233
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5234
        gen_op_ld_T1_A0(ot + s->mem_index);
5235
        gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
5236
        /* load the segment first to handle exceptions properly */
5237
        gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
5238
        gen_movl_seg_T0(s, op, pc_start - s->cs_base);
5239
        /* then put the data */
5240
        gen_op_mov_reg_T1(ot, reg);
5241
        if (s->is_jmp) {
5242
            gen_jmp_im(s->pc - s->cs_base);
5243
            gen_eob(s);
5244
        }
5245
        break;
5246

    
5247
        /************************/
5248
        /* shifts */
5249
    case 0xc0:
5250
    case 0xc1:
5251
        /* shift Ev,Ib */
5252
        shift = 2;
5253
    grp2:
5254
        {
5255
            if ((b & 1) == 0)
5256
                ot = OT_BYTE;
5257
            else
5258
                ot = dflag + OT_WORD;
5259

    
5260
            modrm = ldub_code(s->pc++);
5261
            mod = (modrm >> 6) & 3;
5262
            op = (modrm >> 3) & 7;
5263

    
5264
            if (mod != 3) {
5265
                if (shift == 2) {
5266
                    s->rip_offset = 1;
5267
                }
5268
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5269
                opreg = OR_TMP0;
5270
            } else {
5271
                opreg = (modrm & 7) | REX_B(s);
5272
            }
5273

    
5274
            /* simpler op */
5275
            if (shift == 0) {
5276
                gen_shift(s, op, ot, opreg, OR_ECX);
5277
            } else {
5278
                if (shift == 2) {
5279
                    shift = ldub_code(s->pc++);
5280
                }
5281
                gen_shifti(s, op, ot, opreg, shift);
5282
            }
5283
        }
5284
        break;
5285
    case 0xd0:
5286
    case 0xd1:
5287
        /* shift Ev,1 */
5288
        shift = 1;
5289
        goto grp2;
5290
    case 0xd2:
5291
    case 0xd3:
5292
        /* shift Ev,cl */
5293
        shift = 0;
5294
        goto grp2;
5295

    
5296
    case 0x1a4: /* shld imm */
5297
        op = 0;
5298
        shift = 1;
5299
        goto do_shiftd;
5300
    case 0x1a5: /* shld cl */
5301
        op = 0;
5302
        shift = 0;
5303
        goto do_shiftd;
5304
    case 0x1ac: /* shrd imm */
5305
        op = 1;
5306
        shift = 1;
5307
        goto do_shiftd;
5308
    case 0x1ad: /* shrd cl */
5309
        op = 1;
5310
        shift = 0;
5311
    do_shiftd:
5312
        ot = dflag + OT_WORD;
5313
        modrm = ldub_code(s->pc++);
5314
        mod = (modrm >> 6) & 3;
5315
        rm = (modrm & 7) | REX_B(s);
5316
        reg = ((modrm >> 3) & 7) | rex_r;
5317
        if (mod != 3) {
5318
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5319
            opreg = OR_TMP0;
5320
        } else {
5321
            opreg = rm;
5322
        }
5323
        gen_op_mov_TN_reg(ot, 1, reg);
5324

    
5325
        if (shift) {
5326
            val = ldub_code(s->pc++);
5327
            tcg_gen_movi_tl(cpu_T3, val);
5328
        } else {
5329
            tcg_gen_ld_tl(cpu_T3, cpu_env, offsetof(CPUState, regs[R_ECX]));
5330
        }
5331
        gen_shiftd_rm_T1_T3(s, ot, opreg, op);
5332
        break;
5333

    
5334
        /************************/
5335
        /* floats */
5336
    case 0xd8 ... 0xdf:
5337
        if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
5338
            /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5339
            /* XXX: what to do if illegal op ? */
5340
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5341
            break;
5342
        }
5343
        modrm = ldub_code(s->pc++);
5344
        mod = (modrm >> 6) & 3;
5345
        rm = modrm & 7;
5346
        op = ((b & 7) << 3) | ((modrm >> 3) & 7);
5347
        if (mod != 3) {
5348
            /* memory op */
5349
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5350
            switch(op) {
5351
            case 0x00 ... 0x07: /* fxxxs */
5352
            case 0x10 ... 0x17: /* fixxxl */
5353
            case 0x20 ... 0x27: /* fxxxl */
5354
            case 0x30 ... 0x37: /* fixxx */
5355
                {
5356
                    int op1;
5357
                    op1 = op & 7;
5358

    
5359
                    switch(op >> 4) {
5360
                    case 0:
5361
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5362
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5363
                        gen_helper_flds_FT0(cpu_tmp2_i32);
5364
                        break;
5365
                    case 1:
5366
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5367
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5368
                        gen_helper_fildl_FT0(cpu_tmp2_i32);
5369
                        break;
5370
                    case 2:
5371
                        tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
5372
                                          (s->mem_index >> 2) - 1);
5373
                        gen_helper_fldl_FT0(cpu_tmp1_i64);
5374
                        break;
5375
                    case 3:
5376
                    default:
5377
                        gen_op_lds_T0_A0(OT_WORD + s->mem_index);
5378
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5379
                        gen_helper_fildl_FT0(cpu_tmp2_i32);
5380
                        break;
5381
                    }
5382

    
5383
                    gen_helper_fp_arith_ST0_FT0(op1);
5384
                    if (op1 == 3) {
5385
                        /* fcomp needs pop */
5386
                        gen_helper_fpop();
5387
                    }
5388
                }
5389
                break;
5390
            case 0x08: /* flds */
5391
            case 0x0a: /* fsts */
5392
            case 0x0b: /* fstps */
5393
            case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5394
            case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5395
            case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5396
                switch(op & 7) {
5397
                case 0:
5398
                    switch(op >> 4) {
5399
                    case 0:
5400
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5401
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5402
                        gen_helper_flds_ST0(cpu_tmp2_i32);
5403
                        break;
5404
                    case 1:
5405
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5406
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5407
                        gen_helper_fildl_ST0(cpu_tmp2_i32);
5408
                        break;
5409
                    case 2:
5410
                        tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
5411
                                          (s->mem_index >> 2) - 1);
5412
                        gen_helper_fldl_ST0(cpu_tmp1_i64);
5413
                        break;
5414
                    case 3:
5415
                    default:
5416
                        gen_op_lds_T0_A0(OT_WORD + s->mem_index);
5417
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5418
                        gen_helper_fildl_ST0(cpu_tmp2_i32);
5419
                        break;
5420
                    }
5421
                    break;
5422
                case 1:
5423
                    /* XXX: the corresponding CPUID bit must be tested ! */
5424
                    switch(op >> 4) {
5425
                    case 1:
5426
                        gen_helper_fisttl_ST0(cpu_tmp2_i32);
5427
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5428
                        gen_op_st_T0_A0(OT_LONG + s->mem_index);
5429
                        break;
5430
                    case 2:
5431
                        gen_helper_fisttll_ST0(cpu_tmp1_i64);
5432
                        tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
5433
                                          (s->mem_index >> 2) - 1);
5434
                        break;
5435
                    case 3:
5436
                    default:
5437
                        gen_helper_fistt_ST0(cpu_tmp2_i32);
5438
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5439
                        gen_op_st_T0_A0(OT_WORD + s->mem_index);
5440
                        break;
5441
                    }
5442
                    gen_helper_fpop();
5443
                    break;
5444
                default:
5445
                    switch(op >> 4) {
5446
                    case 0:
5447
                        gen_helper_fsts_ST0(cpu_tmp2_i32);
5448
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5449
                        gen_op_st_T0_A0(OT_LONG + s->mem_index);
5450
                        break;
5451
                    case 1:
5452
                        gen_helper_fistl_ST0(cpu_tmp2_i32);
5453
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5454
                        gen_op_st_T0_A0(OT_LONG + s->mem_index);
5455
                        break;
5456
                    case 2:
5457
                        gen_helper_fstl_ST0(cpu_tmp1_i64);
5458
                        tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
5459
                                          (s->mem_index >> 2) - 1);
5460
                        break;
5461
                    case 3:
5462
                    default:
5463
                        gen_helper_fist_ST0(cpu_tmp2_i32);
5464
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5465
                        gen_op_st_T0_A0(OT_WORD + s->mem_index);
5466
                        break;
5467
                    }
5468
                    if ((op & 7) == 3)
5469
                        gen_helper_fpop();
5470
                    break;
5471
                }
5472
                break;
5473
            case 0x0c: /* fldenv mem */
5474
                if (s->cc_op != CC_OP_DYNAMIC)
5475
                    gen_op_set_cc_op(s->cc_op);
5476
                gen_jmp_im(pc_start - s->cs_base);
5477
                gen_helper_fldenv(
5478
                                   cpu_A0, tcg_const_i32(s->dflag));
5479
                break;
5480
            case 0x0d: /* fldcw mem */
5481
                gen_op_ld_T0_A0(OT_WORD + s->mem_index);
5482
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5483
                gen_helper_fldcw(cpu_tmp2_i32);
5484
                break;
5485
            case 0x0e: /* fnstenv mem */
5486
                if (s->cc_op != CC_OP_DYNAMIC)
5487
                    gen_op_set_cc_op(s->cc_op);
5488
                gen_jmp_im(pc_start - s->cs_base);
5489
                gen_helper_fstenv(cpu_A0, tcg_const_i32(s->dflag));
5490
                break;
5491
            case 0x0f: /* fnstcw mem */
5492
                gen_helper_fnstcw(cpu_tmp2_i32);
5493
                tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5494
                gen_op_st_T0_A0(OT_WORD + s->mem_index);
5495
                break;
5496
            case 0x1d: /* fldt mem */
5497
                if (s->cc_op != CC_OP_DYNAMIC)
5498
                    gen_op_set_cc_op(s->cc_op);
5499
                gen_jmp_im(pc_start - s->cs_base);
5500
                gen_helper_fldt_ST0(cpu_A0);
5501
                break;
5502
            case 0x1f: /* fstpt mem */
5503
                if (s->cc_op != CC_OP_DYNAMIC)
5504
                    gen_op_set_cc_op(s->cc_op);
5505
                gen_jmp_im(pc_start - s->cs_base);
5506
                gen_helper_fstt_ST0(cpu_A0);
5507
                gen_helper_fpop();
5508
                break;
5509
            case 0x2c: /* frstor mem */
5510
                if (s->cc_op != CC_OP_DYNAMIC)
5511
                    gen_op_set_cc_op(s->cc_op);
5512
                gen_jmp_im(pc_start - s->cs_base);
5513
                gen_helper_frstor(cpu_A0, tcg_const_i32(s->dflag));
5514
                break;
5515
            case 0x2e: /* fnsave mem */
5516
                if (s->cc_op != CC_OP_DYNAMIC)
5517
                    gen_op_set_cc_op(s->cc_op);
5518
                gen_jmp_im(pc_start - s->cs_base);
5519
                gen_helper_fsave(cpu_A0, tcg_const_i32(s->dflag));
5520
                break;
5521
            case 0x2f: /* fnstsw mem */
5522
                gen_helper_fnstsw(cpu_tmp2_i32);
5523
                tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5524
                gen_op_st_T0_A0(OT_WORD + s->mem_index);
5525
                break;
5526
            case 0x3c: /* fbld */
5527
                if (s->cc_op != CC_OP_DYNAMIC)
5528
                    gen_op_set_cc_op(s->cc_op);
5529
                gen_jmp_im(pc_start - s->cs_base);
5530
                gen_helper_fbld_ST0(cpu_A0);
5531
                break;
5532
            case 0x3e: /* fbstp */
5533
                if (s->cc_op != CC_OP_DYNAMIC)
5534
                    gen_op_set_cc_op(s->cc_op);
5535
                gen_jmp_im(pc_start - s->cs_base);
5536
                gen_helper_fbst_ST0(cpu_A0);
5537
                gen_helper_fpop();
5538
                break;
5539
            case 0x3d: /* fildll */
5540
                tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
5541
                                  (s->mem_index >> 2) - 1);
5542
                gen_helper_fildll_ST0(cpu_tmp1_i64);
5543
                break;
5544
            case 0x3f: /* fistpll */
5545
                gen_helper_fistll_ST0(cpu_tmp1_i64);
5546
                tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
5547
                                  (s->mem_index >> 2) - 1);
5548
                gen_helper_fpop();
5549
                break;
5550
            default:
5551
                goto illegal_op;
5552
            }
5553
        } else {
5554
            /* register float ops */
5555
            opreg = rm;
5556

    
5557
            switch(op) {
5558
            case 0x08: /* fld sti */
5559
                gen_helper_fpush();
5560
                gen_helper_fmov_ST0_STN(tcg_const_i32((opreg + 1) & 7));
5561
                break;
5562
            case 0x09: /* fxchg sti */
5563
            case 0x29: /* fxchg4 sti, undocumented op */
5564
            case 0x39: /* fxchg7 sti, undocumented op */
5565
                gen_helper_fxchg_ST0_STN(tcg_const_i32(opreg));
5566
                break;
5567
            case 0x0a: /* grp d9/2 */
5568
                switch(rm) {
5569
                case 0: /* fnop */
5570
                    /* check exceptions (FreeBSD FPU probe) */
5571
                    if (s->cc_op != CC_OP_DYNAMIC)
5572
                        gen_op_set_cc_op(s->cc_op);
5573
                    gen_jmp_im(pc_start - s->cs_base);
5574
                    gen_helper_fwait();
5575
                    break;
5576
                default:
5577
                    goto illegal_op;
5578
                }
5579
                break;
5580
            case 0x0c: /* grp d9/4 */
5581
                switch(rm) {
5582
                case 0: /* fchs */
5583
                    gen_helper_fchs_ST0();
5584
                    break;
5585
                case 1: /* fabs */
5586
                    gen_helper_fabs_ST0();
5587
                    break;
5588
                case 4: /* ftst */
5589
                    gen_helper_fldz_FT0();
5590
                    gen_helper_fcom_ST0_FT0();
5591
                    break;
5592
                case 5: /* fxam */
5593
                    gen_helper_fxam_ST0();
5594
                    break;
5595
                default:
5596
                    goto illegal_op;
5597
                }
5598
                break;
5599
            case 0x0d: /* grp d9/5 */
5600
                {
5601
                    switch(rm) {
5602
                    case 0:
5603
                        gen_helper_fpush();
5604
                        gen_helper_fld1_ST0();
5605
                        break;
5606
                    case 1:
5607
                        gen_helper_fpush();
5608
                        gen_helper_fldl2t_ST0();
5609
                        break;
5610
                    case 2:
5611
                        gen_helper_fpush();
5612
                        gen_helper_fldl2e_ST0();
5613
                        break;
5614
                    case 3:
5615
                        gen_helper_fpush();
5616
                        gen_helper_fldpi_ST0();
5617
                        break;
5618
                    case 4:
5619
                        gen_helper_fpush();
5620
                        gen_helper_fldlg2_ST0();
5621
                        break;
5622
                    case 5:
5623
                        gen_helper_fpush();
5624
                        gen_helper_fldln2_ST0();
5625
                        break;
5626
                    case 6:
5627
                        gen_helper_fpush();
5628
                        gen_helper_fldz_ST0();
5629
                        break;
5630
                    default:
5631
                        goto illegal_op;
5632
                    }
5633
                }
5634
                break;
5635
            case 0x0e: /* grp d9/6 */
5636
                switch(rm) {
5637
                case 0: /* f2xm1 */
5638
                    gen_helper_f2xm1();
5639
                    break;
5640
                case 1: /* fyl2x */
5641
                    gen_helper_fyl2x();
5642
                    break;
5643
                case 2: /* fptan */
5644
                    gen_helper_fptan();
5645
                    break;
5646
                case 3: /* fpatan */
5647
                    gen_helper_fpatan();
5648
                    break;
5649
                case 4: /* fxtract */
5650
                    gen_helper_fxtract();
5651
                    break;
5652
                case 5: /* fprem1 */
5653
                    gen_helper_fprem1();
5654
                    break;
5655
                case 6: /* fdecstp */
5656
                    gen_helper_fdecstp();
5657
                    break;
5658
                default:
5659
                case 7: /* fincstp */
5660
                    gen_helper_fincstp();
5661
                    break;
5662
                }
5663
                break;
5664
            case 0x0f: /* grp d9/7 */
5665
                switch(rm) {
5666
                case 0: /* fprem */
5667
                    gen_helper_fprem();
5668
                    break;
5669
                case 1: /* fyl2xp1 */
5670
                    gen_helper_fyl2xp1();
5671
                    break;
5672
                case 2: /* fsqrt */
5673
                    gen_helper_fsqrt();
5674
                    break;
5675
                case 3: /* fsincos */
5676
                    gen_helper_fsincos();
5677
                    break;
5678
                case 5: /* fscale */
5679
                    gen_helper_fscale();
5680
                    break;
5681
                case 4: /* frndint */
5682
                    gen_helper_frndint();
5683
                    break;
5684
                case 6: /* fsin */
5685
                    gen_helper_fsin();
5686
                    break;
5687
                default:
5688
                case 7: /* fcos */
5689
                    gen_helper_fcos();
5690
                    break;
5691
                }
5692
                break;
5693
            case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
5694
            case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
5695
            case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
5696
                {
5697
                    int op1;
5698

    
5699
                    op1 = op & 7;
5700
                    if (op >= 0x20) {
5701
                        gen_helper_fp_arith_STN_ST0(op1, opreg);
5702
                        if (op >= 0x30)
5703
                            gen_helper_fpop();
5704
                    } else {
5705
                        gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5706
                        gen_helper_fp_arith_ST0_FT0(op1);
5707
                    }
5708
                }
5709
                break;
5710
            case 0x02: /* fcom */
5711
            case 0x22: /* fcom2, undocumented op */
5712
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5713
                gen_helper_fcom_ST0_FT0();
5714
                break;
5715
            case 0x03: /* fcomp */
5716
            case 0x23: /* fcomp3, undocumented op */
5717
            case 0x32: /* fcomp5, undocumented op */
5718
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5719
                gen_helper_fcom_ST0_FT0();
5720
                gen_helper_fpop();
5721
                break;
5722
            case 0x15: /* da/5 */
5723
                switch(rm) {
5724
                case 1: /* fucompp */
5725
                    gen_helper_fmov_FT0_STN(tcg_const_i32(1));
5726
                    gen_helper_fucom_ST0_FT0();
5727
                    gen_helper_fpop();
5728
                    gen_helper_fpop();
5729
                    break;
5730
                default:
5731
                    goto illegal_op;
5732
                }
5733
                break;
5734
            case 0x1c:
5735
                switch(rm) {
5736
                case 0: /* feni (287 only, just do nop here) */
5737
                    break;
5738
                case 1: /* fdisi (287 only, just do nop here) */
5739
                    break;
5740
                case 2: /* fclex */
5741
                    gen_helper_fclex();
5742
                    break;
5743
                case 3: /* fninit */
5744
                    gen_helper_fninit();
5745
                    break;
5746
                case 4: /* fsetpm (287 only, just do nop here) */
5747
                    break;
5748
                default:
5749
                    goto illegal_op;
5750
                }
5751
                break;
5752
            case 0x1d: /* fucomi */
5753
                if (s->cc_op != CC_OP_DYNAMIC)
5754
                    gen_op_set_cc_op(s->cc_op);
5755
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5756
                gen_helper_fucomi_ST0_FT0();
5757
                s->cc_op = CC_OP_EFLAGS;
5758
                break;
5759
            case 0x1e: /* fcomi */
5760
                if (s->cc_op != CC_OP_DYNAMIC)
5761
                    gen_op_set_cc_op(s->cc_op);
5762
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5763
                gen_helper_fcomi_ST0_FT0();
5764
                s->cc_op = CC_OP_EFLAGS;
5765
                break;
5766
            case 0x28: /* ffree sti */
5767
                gen_helper_ffree_STN(tcg_const_i32(opreg));
5768
                break;
5769
            case 0x2a: /* fst sti */
5770
                gen_helper_fmov_STN_ST0(tcg_const_i32(opreg));
5771
                break;
5772
            case 0x2b: /* fstp sti */
5773
            case 0x0b: /* fstp1 sti, undocumented op */
5774
            case 0x3a: /* fstp8 sti, undocumented op */
5775
            case 0x3b: /* fstp9 sti, undocumented op */
5776
                gen_helper_fmov_STN_ST0(tcg_const_i32(opreg));
5777
                gen_helper_fpop();
5778
                break;
5779
            case 0x2c: /* fucom st(i) */
5780
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5781
                gen_helper_fucom_ST0_FT0();
5782
                break;
5783
            case 0x2d: /* fucomp st(i) */
5784
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5785
                gen_helper_fucom_ST0_FT0();
5786
                gen_helper_fpop();
5787
                break;
5788
            case 0x33: /* de/3 */
5789
                switch(rm) {
5790
                case 1: /* fcompp */
5791
                    gen_helper_fmov_FT0_STN(tcg_const_i32(1));
5792
                    gen_helper_fcom_ST0_FT0();
5793
                    gen_helper_fpop();
5794
                    gen_helper_fpop();
5795
                    break;
5796
                default:
5797
                    goto illegal_op;
5798
                }
5799
                break;
5800
            case 0x38: /* ffreep sti, undocumented op */
5801
                gen_helper_ffree_STN(tcg_const_i32(opreg));
5802
                gen_helper_fpop();
5803
                break;
5804
            case 0x3c: /* df/4 */
5805
                switch(rm) {
5806
                case 0:
5807
                    gen_helper_fnstsw(cpu_tmp2_i32);
5808
                    tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5809
                    gen_op_mov_reg_T0(OT_WORD, R_EAX);
5810
                    break;
5811
                default:
5812
                    goto illegal_op;
5813
                }
5814
                break;
5815
            case 0x3d: /* fucomip */
5816
                if (s->cc_op != CC_OP_DYNAMIC)
5817
                    gen_op_set_cc_op(s->cc_op);
5818
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5819
                gen_helper_fucomi_ST0_FT0();
5820
                gen_helper_fpop();
5821
                s->cc_op = CC_OP_EFLAGS;
5822
                break;
5823
            case 0x3e: /* fcomip */
5824
                if (s->cc_op != CC_OP_DYNAMIC)
5825
                    gen_op_set_cc_op(s->cc_op);
5826
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5827
                gen_helper_fcomi_ST0_FT0();
5828
                gen_helper_fpop();
5829
                s->cc_op = CC_OP_EFLAGS;
5830
                break;
5831
            case 0x10 ... 0x13: /* fcmovxx */
5832
            case 0x18 ... 0x1b:
5833
                {
5834
                    int op1, l1;
5835
                    static const uint8_t fcmov_cc[8] = {
5836
                        (JCC_B << 1),
5837
                        (JCC_Z << 1),
5838
                        (JCC_BE << 1),
5839
                        (JCC_P << 1),
5840
                    };
5841
                    op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
5842
                    l1 = gen_new_label();
5843
                    gen_jcc1(s, s->cc_op, op1, l1);
5844
                    gen_helper_fmov_ST0_STN(tcg_const_i32(opreg));
5845
                    gen_set_label(l1);
5846
                }
5847
                break;
5848
            default:
5849
                goto illegal_op;
5850
            }
5851
        }
5852
        break;
5853
        /************************/
5854
        /* string ops */
5855

    
5856
    case 0xa4: /* movsS */
5857
    case 0xa5:
5858
        if ((b & 1) == 0)
5859
            ot = OT_BYTE;
5860
        else
5861
            ot = dflag + OT_WORD;
5862

    
5863
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5864
            gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5865
        } else {
5866
            gen_movs(s, ot);
5867
        }
5868
        break;
5869

    
5870
    case 0xaa: /* stosS */
5871
    case 0xab:
5872
        if ((b & 1) == 0)
5873
            ot = OT_BYTE;
5874
        else
5875
            ot = dflag + OT_WORD;
5876

    
5877
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5878
            gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5879
        } else {
5880
            gen_stos(s, ot);
5881
        }
5882
        break;
5883
    case 0xac: /* lodsS */
5884
    case 0xad:
5885
        if ((b & 1) == 0)
5886
            ot = OT_BYTE;
5887
        else
5888
            ot = dflag + OT_WORD;
5889
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5890
            gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5891
        } else {
5892
            gen_lods(s, ot);
5893
        }
5894
        break;
5895
    case 0xae: /* scasS */
5896
    case 0xaf:
5897
        if ((b & 1) == 0)
5898
            ot = OT_BYTE;
5899
        else
5900
            ot = dflag + OT_WORD;
5901
        if (prefixes & PREFIX_REPNZ) {
5902
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
5903
        } else if (prefixes & PREFIX_REPZ) {
5904
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
5905
        } else {
5906
            gen_scas(s, ot);
5907
            s->cc_op = CC_OP_SUBB + ot;
5908
        }
5909
        break;
5910

    
5911
    case 0xa6: /* cmpsS */
5912
    case 0xa7:
5913
        if ((b & 1) == 0)
5914
            ot = OT_BYTE;
5915
        else
5916
            ot = dflag + OT_WORD;
5917
        if (prefixes & PREFIX_REPNZ) {
5918
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
5919
        } else if (prefixes & PREFIX_REPZ) {
5920
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
5921
        } else {
5922
            gen_cmps(s, ot);
5923
            s->cc_op = CC_OP_SUBB + ot;
5924
        }
5925
        break;
5926
    case 0x6c: /* insS */
5927
    case 0x6d:
5928
        if ((b & 1) == 0)
5929
            ot = OT_BYTE;
5930
        else
5931
            ot = dflag ? OT_LONG : OT_WORD;
5932
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5933
        gen_op_andl_T0_ffff();
5934
        gen_check_io(s, ot, pc_start - s->cs_base, 
5935
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
5936
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5937
            gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5938
        } else {
5939
            gen_ins(s, ot);
5940
            if (use_icount) {
5941
                gen_jmp(s, s->pc - s->cs_base);
5942
            }
5943
        }
5944
        break;
5945
    case 0x6e: /* outsS */
5946
    case 0x6f:
5947
        if ((b & 1) == 0)
5948
            ot = OT_BYTE;
5949
        else
5950
            ot = dflag ? OT_LONG : OT_WORD;
5951
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5952
        gen_op_andl_T0_ffff();
5953
        gen_check_io(s, ot, pc_start - s->cs_base,
5954
                     svm_is_rep(prefixes) | 4);
5955
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5956
            gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5957
        } else {
5958
            gen_outs(s, ot);
5959
            if (use_icount) {
5960
                gen_jmp(s, s->pc - s->cs_base);
5961
            }
5962
        }
5963
        break;
5964

    
5965
        /************************/
5966
        /* port I/O */
5967

    
5968
    case 0xe4:
5969
    case 0xe5:
5970
        if ((b & 1) == 0)
5971
            ot = OT_BYTE;
5972
        else
5973
            ot = dflag ? OT_LONG : OT_WORD;
5974
        val = ldub_code(s->pc++);
5975
        gen_op_movl_T0_im(val);
5976
        gen_check_io(s, ot, pc_start - s->cs_base,
5977
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
5978
        if (use_icount)
5979
            gen_io_start();
5980
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5981
        gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
5982
        gen_op_mov_reg_T1(ot, R_EAX);
5983
        if (use_icount) {
5984
            gen_io_end();
5985
            gen_jmp(s, s->pc - s->cs_base);
5986
        }
5987
        break;
5988
    case 0xe6:
5989
    case 0xe7:
5990
        if ((b & 1) == 0)
5991
            ot = OT_BYTE;
5992
        else
5993
            ot = dflag ? OT_LONG : OT_WORD;
5994
        val = ldub_code(s->pc++);
5995
        gen_op_movl_T0_im(val);
5996
        gen_check_io(s, ot, pc_start - s->cs_base,
5997
                     svm_is_rep(prefixes));
5998
        gen_op_mov_TN_reg(ot, 1, R_EAX);
5999

    
6000
        if (use_icount)
6001
            gen_io_start();
6002
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6003
        tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
6004
        tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
6005
        gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6006
        if (use_icount) {
6007
            gen_io_end();
6008
            gen_jmp(s, s->pc - s->cs_base);
6009
        }
6010
        break;
6011
    case 0xec:
6012
    case 0xed:
6013
        if ((b & 1) == 0)
6014
            ot = OT_BYTE;
6015
        else
6016
            ot = dflag ? OT_LONG : OT_WORD;
6017
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6018
        gen_op_andl_T0_ffff();
6019
        gen_check_io(s, ot, pc_start - s->cs_base,
6020
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6021
        if (use_icount)
6022
            gen_io_start();
6023
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6024
        gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
6025
        gen_op_mov_reg_T1(ot, R_EAX);
6026
        if (use_icount) {
6027
            gen_io_end();
6028
            gen_jmp(s, s->pc - s->cs_base);
6029
        }
6030
        break;
6031
    case 0xee:
6032
    case 0xef:
6033
        if ((b & 1) == 0)
6034
            ot = OT_BYTE;
6035
        else
6036
            ot = dflag ? OT_LONG : OT_WORD;
6037
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6038
        gen_op_andl_T0_ffff();
6039
        gen_check_io(s, ot, pc_start - s->cs_base,
6040
                     svm_is_rep(prefixes));
6041
        gen_op_mov_TN_reg(ot, 1, R_EAX);
6042

    
6043
        if (use_icount)
6044
            gen_io_start();
6045
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6046
        tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
6047
        tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
6048
        gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6049
        if (use_icount) {
6050
            gen_io_end();
6051
            gen_jmp(s, s->pc - s->cs_base);
6052
        }
6053
        break;
6054

    
6055
        /************************/
6056
        /* control */
6057
    case 0xc2: /* ret im */
6058
        val = ldsw_code(s->pc);
6059
        s->pc += 2;
6060
        gen_pop_T0(s);
6061
        if (CODE64(s) && s->dflag)
6062
            s->dflag = 2;
6063
        gen_stack_update(s, val + (2 << s->dflag));
6064
        if (s->dflag == 0)
6065
            gen_op_andl_T0_ffff();
6066
        gen_op_jmp_T0();
6067
        gen_eob(s);
6068
        break;
6069
    case 0xc3: /* ret */
6070
        gen_pop_T0(s);
6071
        gen_pop_update(s);
6072
        if (s->dflag == 0)
6073
            gen_op_andl_T0_ffff();
6074
        gen_op_jmp_T0();
6075
        gen_eob(s);
6076
        break;
6077
    case 0xca: /* lret im */
6078
        val = ldsw_code(s->pc);
6079
        s->pc += 2;
6080
    do_lret:
6081
        if (s->pe && !s->vm86) {
6082
            if (s->cc_op != CC_OP_DYNAMIC)
6083
                gen_op_set_cc_op(s->cc_op);
6084
            gen_jmp_im(pc_start - s->cs_base);
6085
            gen_helper_lret_protected(tcg_const_i32(s->dflag),
6086
                                      tcg_const_i32(val));
6087
        } else {
6088
            gen_stack_A0(s);
6089
            /* pop offset */
6090
            gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
6091
            if (s->dflag == 0)
6092
                gen_op_andl_T0_ffff();
6093
            /* NOTE: keeping EIP updated is not a problem in case of
6094
               exception */
6095
            gen_op_jmp_T0();
6096
            /* pop selector */
6097
            gen_op_addl_A0_im(2 << s->dflag);
6098
            gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
6099
            gen_op_movl_seg_T0_vm(R_CS);
6100
            /* add stack offset */
6101
            gen_stack_update(s, val + (4 << s->dflag));
6102
        }
6103
        gen_eob(s);
6104
        break;
6105
    case 0xcb: /* lret */
6106
        val = 0;
6107
        goto do_lret;
6108
    case 0xcf: /* iret */
6109
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
6110
        if (!s->pe) {
6111
            /* real mode */
6112
            gen_helper_iret_real(tcg_const_i32(s->dflag));
6113
            s->cc_op = CC_OP_EFLAGS;
6114
        } else if (s->vm86) {
6115
            if (s->iopl != 3) {
6116
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6117
            } else {
6118
                gen_helper_iret_real(tcg_const_i32(s->dflag));
6119
                s->cc_op = CC_OP_EFLAGS;
6120
            }
6121
        } else {
6122
            if (s->cc_op != CC_OP_DYNAMIC)
6123
                gen_op_set_cc_op(s->cc_op);
6124
            gen_jmp_im(pc_start - s->cs_base);
6125
            gen_helper_iret_protected(tcg_const_i32(s->dflag), 
6126
                                      tcg_const_i32(s->pc - s->cs_base));
6127
            s->cc_op = CC_OP_EFLAGS;
6128
        }
6129
        gen_eob(s);
6130
        break;
6131
    case 0xe8: /* call im */
6132
        {
6133
            if (dflag)
6134
                tval = (int32_t)insn_get(s, OT_LONG);
6135
            else
6136
                tval = (int16_t)insn_get(s, OT_WORD);
6137
            next_eip = s->pc - s->cs_base;
6138
            tval += next_eip;
6139
            if (s->dflag == 0)
6140
                tval &= 0xffff;
6141
            gen_movtl_T0_im(next_eip);
6142
            gen_push_T0(s);
6143
            gen_jmp(s, tval);
6144
        }
6145
        break;
6146
    case 0x9a: /* lcall im */
6147
        {
6148
            unsigned int selector, offset;
6149

    
6150
            if (CODE64(s))
6151
                goto illegal_op;
6152
            ot = dflag ? OT_LONG : OT_WORD;
6153
            offset = insn_get(s, ot);
6154
            selector = insn_get(s, OT_WORD);
6155

    
6156
            gen_op_movl_T0_im(selector);
6157
            gen_op_movl_T1_imu(offset);
6158
        }
6159
        goto do_lcall;
6160
    case 0xe9: /* jmp im */
6161
        if (dflag)
6162
            tval = (int32_t)insn_get(s, OT_LONG);
6163
        else
6164
            tval = (int16_t)insn_get(s, OT_WORD);
6165
        tval += s->pc - s->cs_base;
6166
        if (s->dflag == 0)
6167
            tval &= 0xffff;
6168
        else if(!CODE64(s))
6169
            tval &= 0xffffffff;
6170
        gen_jmp(s, tval);
6171
        break;
6172
    case 0xea: /* ljmp im */
6173
        {
6174
            unsigned int selector, offset;
6175

    
6176
            if (CODE64(s))
6177
                goto illegal_op;
6178
            ot = dflag ? OT_LONG : OT_WORD;
6179
            offset = insn_get(s, ot);
6180
            selector = insn_get(s, OT_WORD);
6181

    
6182
            gen_op_movl_T0_im(selector);
6183
            gen_op_movl_T1_imu(offset);
6184
        }
6185
        goto do_ljmp;
6186
    case 0xeb: /* jmp Jb */
6187
        tval = (int8_t)insn_get(s, OT_BYTE);
6188
        tval += s->pc - s->cs_base;
6189
        if (s->dflag == 0)
6190
            tval &= 0xffff;
6191
        gen_jmp(s, tval);
6192
        break;
6193
    case 0x70 ... 0x7f: /* jcc Jb */
6194
        tval = (int8_t)insn_get(s, OT_BYTE);
6195
        goto do_jcc;
6196
    case 0x180 ... 0x18f: /* jcc Jv */
6197
        if (dflag) {
6198
            tval = (int32_t)insn_get(s, OT_LONG);
6199
        } else {
6200
            tval = (int16_t)insn_get(s, OT_WORD);
6201
        }
6202
    do_jcc:
6203
        next_eip = s->pc - s->cs_base;
6204
        tval += next_eip;
6205
        if (s->dflag == 0)
6206
            tval &= 0xffff;
6207
        gen_jcc(s, b, tval, next_eip);
6208
        break;
6209

    
6210
    case 0x190 ... 0x19f: /* setcc Gv */
6211
        modrm = ldub_code(s->pc++);
6212
        gen_setcc(s, b);
6213
        gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
6214
        break;
6215
    case 0x140 ... 0x14f: /* cmov Gv, Ev */
6216
        {
6217
            int l1;
6218
            TCGv t0;
6219

    
6220
            ot = dflag + OT_WORD;
6221
            modrm = ldub_code(s->pc++);
6222
            reg = ((modrm >> 3) & 7) | rex_r;
6223
            mod = (modrm >> 6) & 3;
6224
            t0 = tcg_temp_local_new();
6225
            if (mod != 3) {
6226
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6227
                gen_op_ld_v(ot + s->mem_index, t0, cpu_A0);
6228
            } else {
6229
                rm = (modrm & 7) | REX_B(s);
6230
                gen_op_mov_v_reg(ot, t0, rm);
6231
            }
6232
#ifdef TARGET_X86_64
6233
            if (ot == OT_LONG) {
6234
                /* XXX: specific Intel behaviour ? */
6235
                l1 = gen_new_label();
6236
                gen_jcc1(s, s->cc_op, b ^ 1, l1);
6237
                tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
6238
                gen_set_label(l1);
6239
                tcg_gen_movi_tl(cpu_tmp0, 0);
6240
                tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_LH_OFFSET);
6241
            } else
6242
#endif
6243
            {
6244
                l1 = gen_new_label();
6245
                gen_jcc1(s, s->cc_op, b ^ 1, l1);
6246
                gen_op_mov_reg_v(ot, reg, t0);
6247
                gen_set_label(l1);
6248
            }
6249
            tcg_temp_free(t0);
6250
        }
6251
        break;
6252

    
6253
        /************************/
6254
        /* flags */
6255
    case 0x9c: /* pushf */
6256
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
6257
        if (s->vm86 && s->iopl != 3) {
6258
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6259
        } else {
6260
            if (s->cc_op != CC_OP_DYNAMIC)
6261
                gen_op_set_cc_op(s->cc_op);
6262
            gen_helper_read_eflags(cpu_T[0]);
6263
            gen_push_T0(s);
6264
        }
6265
        break;
6266
    case 0x9d: /* popf */
6267
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
6268
        if (s->vm86 && s->iopl != 3) {
6269
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6270
        } else {
6271
            gen_pop_T0(s);
6272
            if (s->cpl == 0) {
6273
                if (s->dflag) {
6274
                    gen_helper_write_eflags(cpu_T[0],
6275
                                       tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK)));
6276
                } else {
6277
                    gen_helper_write_eflags(cpu_T[0],
6278
                                       tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff));
6279
                }
6280
            } else {
6281
                if (s->cpl <= s->iopl) {
6282
                    if (s->dflag) {
6283
                        gen_helper_write_eflags(cpu_T[0],
6284
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK)));
6285
                    } else {
6286
                        gen_helper_write_eflags(cpu_T[0],
6287
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff));
6288
                    }
6289
                } else {
6290
                    if (s->dflag) {
6291
                        gen_helper_write_eflags(cpu_T[0],
6292
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK)));
6293
                    } else {
6294
                        gen_helper_write_eflags(cpu_T[0],
6295
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff));
6296
                    }
6297
                }
6298
            }
6299
            gen_pop_update(s);
6300
            s->cc_op = CC_OP_EFLAGS;
6301
            /* abort translation because TF flag may change */
6302
            gen_jmp_im(s->pc - s->cs_base);
6303
            gen_eob(s);
6304
        }
6305
        break;
6306
    case 0x9e: /* sahf */
6307
        if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6308
            goto illegal_op;
6309
        gen_op_mov_TN_reg(OT_BYTE, 0, R_AH);
6310
        if (s->cc_op != CC_OP_DYNAMIC)
6311
            gen_op_set_cc_op(s->cc_op);
6312
        gen_compute_eflags(cpu_cc_src);
6313
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
6314
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], CC_S | CC_Z | CC_A | CC_P | CC_C);
6315
        tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T[0]);
6316
        s->cc_op = CC_OP_EFLAGS;
6317
        break;
6318
    case 0x9f: /* lahf */
6319
        if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6320
            goto illegal_op;
6321
        if (s->cc_op != CC_OP_DYNAMIC)
6322
            gen_op_set_cc_op(s->cc_op);
6323
        gen_compute_eflags(cpu_T[0]);
6324
        /* Note: gen_compute_eflags() only gives the condition codes */
6325
        tcg_gen_ori_tl(cpu_T[0], cpu_T[0], 0x02);
6326
        gen_op_mov_reg_T0(OT_BYTE, R_AH);
6327
        break;
6328
    case 0xf5: /* cmc */
6329
        if (s->cc_op != CC_OP_DYNAMIC)
6330
            gen_op_set_cc_op(s->cc_op);
6331
        gen_compute_eflags(cpu_cc_src);
6332
        tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6333
        s->cc_op = CC_OP_EFLAGS;
6334
        break;
6335
    case 0xf8: /* clc */
6336
        if (s->cc_op != CC_OP_DYNAMIC)
6337
            gen_op_set_cc_op(s->cc_op);
6338
        gen_compute_eflags(cpu_cc_src);
6339
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
6340
        s->cc_op = CC_OP_EFLAGS;
6341
        break;
6342
    case 0xf9: /* stc */
6343
        if (s->cc_op != CC_OP_DYNAMIC)
6344
            gen_op_set_cc_op(s->cc_op);
6345
        gen_compute_eflags(cpu_cc_src);
6346
        tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6347
        s->cc_op = CC_OP_EFLAGS;
6348
        break;
6349
    case 0xfc: /* cld */
6350
        tcg_gen_movi_i32(cpu_tmp2_i32, 1);
6351
        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUState, df));
6352
        break;
6353
    case 0xfd: /* std */
6354
        tcg_gen_movi_i32(cpu_tmp2_i32, -1);
6355
        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUState, df));
6356
        break;
6357

    
6358
        /************************/
6359
        /* bit operations */
6360
    case 0x1ba: /* bt/bts/btr/btc Gv, im */
6361
        ot = dflag + OT_WORD;
6362
        modrm = ldub_code(s->pc++);
6363
        op = (modrm >> 3) & 7;
6364
        mod = (modrm >> 6) & 3;
6365
        rm = (modrm & 7) | REX_B(s);
6366
        if (mod != 3) {
6367
            s->rip_offset = 1;
6368
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6369
            gen_op_ld_T0_A0(ot + s->mem_index);
6370
        } else {
6371
            gen_op_mov_TN_reg(ot, 0, rm);
6372
        }
6373
        /* load shift */
6374
        val = ldub_code(s->pc++);
6375
        gen_op_movl_T1_im(val);
6376
        if (op < 4)
6377
            goto illegal_op;
6378
        op -= 4;
6379
        goto bt_op;
6380
    case 0x1a3: /* bt Gv, Ev */
6381
        op = 0;
6382
        goto do_btx;
6383
    case 0x1ab: /* bts */
6384
        op = 1;
6385
        goto do_btx;
6386
    case 0x1b3: /* btr */
6387
        op = 2;
6388
        goto do_btx;
6389
    case 0x1bb: /* btc */
6390
        op = 3;
6391
    do_btx:
6392
        ot = dflag + OT_WORD;
6393
        modrm = ldub_code(s->pc++);
6394
        reg = ((modrm >> 3) & 7) | rex_r;
6395
        mod = (modrm >> 6) & 3;
6396
        rm = (modrm & 7) | REX_B(s);
6397
        gen_op_mov_TN_reg(OT_LONG, 1, reg);
6398
        if (mod != 3) {
6399
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6400
            /* specific case: we need to add a displacement */
6401
            gen_exts(ot, cpu_T[1]);
6402
            tcg_gen_sari_tl(cpu_tmp0, cpu_T[1], 3 + ot);
6403
            tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
6404
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
6405
            gen_op_ld_T0_A0(ot + s->mem_index);
6406
        } else {
6407
            gen_op_mov_TN_reg(ot, 0, rm);
6408
        }
6409
    bt_op:
6410
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], (1 << (3 + ot)) - 1);
6411
        switch(op) {
6412
        case 0:
6413
            tcg_gen_shr_tl(cpu_cc_src, cpu_T[0], cpu_T[1]);
6414
            tcg_gen_movi_tl(cpu_cc_dst, 0);
6415
            break;
6416
        case 1:
6417
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6418
            tcg_gen_movi_tl(cpu_tmp0, 1);
6419
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6420
            tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6421
            break;
6422
        case 2:
6423
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6424
            tcg_gen_movi_tl(cpu_tmp0, 1);
6425
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6426
            tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
6427
            tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6428
            break;
6429
        default:
6430
        case 3:
6431
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6432
            tcg_gen_movi_tl(cpu_tmp0, 1);
6433
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6434
            tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6435
            break;
6436
        }
6437
        s->cc_op = CC_OP_SARB + ot;
6438
        if (op != 0) {
6439
            if (mod != 3)
6440
                gen_op_st_T0_A0(ot + s->mem_index);
6441
            else
6442
                gen_op_mov_reg_T0(ot, rm);
6443
            tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
6444
            tcg_gen_movi_tl(cpu_cc_dst, 0);
6445
        }
6446
        break;
6447
    case 0x1bc: /* bsf */
6448
    case 0x1bd: /* bsr */
6449
        {
6450
            int label1;
6451
            TCGv t0;
6452

    
6453
            ot = dflag + OT_WORD;
6454
            modrm = ldub_code(s->pc++);
6455
            reg = ((modrm >> 3) & 7) | rex_r;
6456
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
6457
            gen_extu(ot, cpu_T[0]);
6458
            label1 = gen_new_label();
6459
            tcg_gen_movi_tl(cpu_cc_dst, 0);
6460
            t0 = tcg_temp_local_new();
6461
            tcg_gen_mov_tl(t0, cpu_T[0]);
6462
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, label1);
6463
            if (b & 1) {
6464
                gen_helper_bsr(cpu_T[0], t0);
6465
            } else {
6466
                gen_helper_bsf(cpu_T[0], t0);
6467
            }
6468
            gen_op_mov_reg_T0(ot, reg);
6469
            tcg_gen_movi_tl(cpu_cc_dst, 1);
6470
            gen_set_label(label1);
6471
            tcg_gen_discard_tl(cpu_cc_src);
6472
            s->cc_op = CC_OP_LOGICB + ot;
6473
            tcg_temp_free(t0);
6474
        }
6475
        break;
6476
        /************************/
6477
        /* bcd */
6478
    case 0x27: /* daa */
6479
        if (CODE64(s))
6480
            goto illegal_op;
6481
        if (s->cc_op != CC_OP_DYNAMIC)
6482
            gen_op_set_cc_op(s->cc_op);
6483
        gen_helper_daa();
6484
        s->cc_op = CC_OP_EFLAGS;
6485
        break;
6486
    case 0x2f: /* das */
6487
        if (CODE64(s))
6488
            goto illegal_op;
6489
        if (s->cc_op != CC_OP_DYNAMIC)
6490
            gen_op_set_cc_op(s->cc_op);
6491
        gen_helper_das();
6492
        s->cc_op = CC_OP_EFLAGS;
6493
        break;
6494
    case 0x37: /* aaa */
6495
        if (CODE64(s))
6496
            goto illegal_op;
6497
        if (s->cc_op != CC_OP_DYNAMIC)
6498
            gen_op_set_cc_op(s->cc_op);
6499
        gen_helper_aaa();
6500
        s->cc_op = CC_OP_EFLAGS;
6501
        break;
6502
    case 0x3f: /* aas */
6503
        if (CODE64(s))
6504
            goto illegal_op;
6505
        if (s->cc_op != CC_OP_DYNAMIC)
6506
            gen_op_set_cc_op(s->cc_op);
6507
        gen_helper_aas();
6508
        s->cc_op = CC_OP_EFLAGS;
6509
        break;
6510
    case 0xd4: /* aam */
6511
        if (CODE64(s))
6512
            goto illegal_op;
6513
        val = ldub_code(s->pc++);
6514
        if (val == 0) {
6515
            gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
6516
        } else {
6517
            gen_helper_aam(tcg_const_i32(val));
6518
            s->cc_op = CC_OP_LOGICB;
6519
        }
6520
        break;
6521
    case 0xd5: /* aad */
6522
        if (CODE64(s))
6523
            goto illegal_op;
6524
        val = ldub_code(s->pc++);
6525
        gen_helper_aad(tcg_const_i32(val));
6526
        s->cc_op = CC_OP_LOGICB;
6527
        break;
6528
        /************************/
6529
        /* misc */
6530
    case 0x90: /* nop */
6531
        /* XXX: xchg + rex handling */
6532
        /* XXX: correct lock test for all insn */
6533
        if (prefixes & PREFIX_LOCK)
6534
            goto illegal_op;
6535
        if (prefixes & PREFIX_REPZ) {
6536
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_PAUSE);
6537
        }
6538
        break;
6539
    case 0x9b: /* fwait */
6540
        if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
6541
            (HF_MP_MASK | HF_TS_MASK)) {
6542
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6543
        } else {
6544
            if (s->cc_op != CC_OP_DYNAMIC)
6545
                gen_op_set_cc_op(s->cc_op);
6546
            gen_jmp_im(pc_start - s->cs_base);
6547
            gen_helper_fwait();
6548
        }
6549
        break;
6550
    case 0xcc: /* int3 */
6551
        gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
6552
        break;
6553
    case 0xcd: /* int N */
6554
        val = ldub_code(s->pc++);
6555
        if (s->vm86 && s->iopl != 3) {
6556
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6557
        } else {
6558
            gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
6559
        }
6560
        break;
6561
    case 0xce: /* into */
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_jmp_im(pc_start - s->cs_base);
6567
        gen_helper_into(tcg_const_i32(s->pc - pc_start));
6568
        break;
6569
#ifdef WANT_ICEBP
6570
    case 0xf1: /* icebp (undocumented, exits to external debugger) */
6571
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
6572
#if 1
6573
        gen_debug(s, pc_start - s->cs_base);
6574
#else
6575
        /* start debug */
6576
        tb_flush(cpu_single_env);
6577
        cpu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
6578
#endif
6579
        break;
6580
#endif
6581
    case 0xfa: /* cli */
6582
        if (!s->vm86) {
6583
            if (s->cpl <= s->iopl) {
6584
                gen_helper_cli();
6585
            } else {
6586
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6587
            }
6588
        } else {
6589
            if (s->iopl == 3) {
6590
                gen_helper_cli();
6591
            } else {
6592
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6593
            }
6594
        }
6595
        break;
6596
    case 0xfb: /* sti */
6597
        if (!s->vm86) {
6598
            if (s->cpl <= s->iopl) {
6599
            gen_sti:
6600
                gen_helper_sti();
6601
                /* interruptions are enabled only the first insn after sti */
6602
                /* If several instructions disable interrupts, only the
6603
                   _first_ does it */
6604
                if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
6605
                    gen_helper_set_inhibit_irq();
6606
                /* give a chance to handle pending irqs */
6607
                gen_jmp_im(s->pc - s->cs_base);
6608
                gen_eob(s);
6609
            } else {
6610
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6611
            }
6612
        } else {
6613
            if (s->iopl == 3) {
6614
                goto gen_sti;
6615
            } else {
6616
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6617
            }
6618
        }
6619
        break;
6620
    case 0x62: /* bound */
6621
        if (CODE64(s))
6622
            goto illegal_op;
6623
        ot = dflag ? OT_LONG : OT_WORD;
6624
        modrm = ldub_code(s->pc++);
6625
        reg = (modrm >> 3) & 7;
6626
        mod = (modrm >> 6) & 3;
6627
        if (mod == 3)
6628
            goto illegal_op;
6629
        gen_op_mov_TN_reg(ot, 0, reg);
6630
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6631
        gen_jmp_im(pc_start - s->cs_base);
6632
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6633
        if (ot == OT_WORD)
6634
            gen_helper_boundw(cpu_A0, cpu_tmp2_i32);
6635
        else
6636
            gen_helper_boundl(cpu_A0, cpu_tmp2_i32);
6637
        break;
6638
    case 0x1c8 ... 0x1cf: /* bswap reg */
6639
        reg = (b & 7) | REX_B(s);
6640
#ifdef TARGET_X86_64
6641
        if (dflag == 2) {
6642
            gen_op_mov_TN_reg(OT_QUAD, 0, reg);
6643
            tcg_gen_bswap_i64(cpu_T[0], cpu_T[0]);
6644
            gen_op_mov_reg_T0(OT_QUAD, reg);
6645
        } else
6646
        {
6647
            TCGv_i32 tmp0;
6648
            gen_op_mov_TN_reg(OT_LONG, 0, reg);
6649
            
6650
            tmp0 = tcg_temp_new_i32();
6651
            tcg_gen_trunc_i64_i32(tmp0, cpu_T[0]);
6652
            tcg_gen_bswap_i32(tmp0, tmp0);
6653
            tcg_gen_extu_i32_i64(cpu_T[0], tmp0);
6654
            gen_op_mov_reg_T0(OT_LONG, reg);
6655
        }
6656
#else
6657
        {
6658
            gen_op_mov_TN_reg(OT_LONG, 0, reg);
6659
            tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]);
6660
            gen_op_mov_reg_T0(OT_LONG, reg);
6661
        }
6662
#endif
6663
        break;
6664
    case 0xd6: /* salc */
6665
        if (CODE64(s))
6666
            goto illegal_op;
6667
        if (s->cc_op != CC_OP_DYNAMIC)
6668
            gen_op_set_cc_op(s->cc_op);
6669
        gen_compute_eflags_c(cpu_T[0]);
6670
        tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
6671
        gen_op_mov_reg_T0(OT_BYTE, R_EAX);
6672
        break;
6673
    case 0xe0: /* loopnz */
6674
    case 0xe1: /* loopz */
6675
    case 0xe2: /* loop */
6676
    case 0xe3: /* jecxz */
6677
        {
6678
            int l1, l2, l3;
6679

    
6680
            tval = (int8_t)insn_get(s, OT_BYTE);
6681
            next_eip = s->pc - s->cs_base;
6682
            tval += next_eip;
6683
            if (s->dflag == 0)
6684
                tval &= 0xffff;
6685

    
6686
            l1 = gen_new_label();
6687
            l2 = gen_new_label();
6688
            l3 = gen_new_label();
6689
            b &= 3;
6690
            switch(b) {
6691
            case 0: /* loopnz */
6692
            case 1: /* loopz */
6693
                if (s->cc_op != CC_OP_DYNAMIC)
6694
                    gen_op_set_cc_op(s->cc_op);
6695
                gen_op_add_reg_im(s->aflag, R_ECX, -1);
6696
                gen_op_jz_ecx(s->aflag, l3);
6697
                gen_compute_eflags(cpu_tmp0);
6698
                tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_Z);
6699
                if (b == 0) {
6700
                    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
6701
                } else {
6702
                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, l1);
6703
                }
6704
                break;
6705
            case 2: /* loop */
6706
                gen_op_add_reg_im(s->aflag, R_ECX, -1);
6707
                gen_op_jnz_ecx(s->aflag, l1);
6708
                break;
6709
            default:
6710
            case 3: /* jcxz */
6711
                gen_op_jz_ecx(s->aflag, l1);
6712
                break;
6713
            }
6714

    
6715
            gen_set_label(l3);
6716
            gen_jmp_im(next_eip);
6717
            tcg_gen_br(l2);
6718

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

    
7147
            modrm = ldub_code(s->pc++);
7148
            reg = ((modrm >> 3) & 7) | rex_r;
7149
            mod = (modrm >> 6) & 3;
7150
            rm = (modrm & 7) | REX_B(s);
7151

    
7152
            if (mod == 3) {
7153
                gen_op_mov_TN_reg(OT_LONG, 0, rm);
7154
                /* sign extend */
7155
                if (d_ot == OT_QUAD)
7156
                    tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
7157
                gen_op_mov_reg_T0(d_ot, reg);
7158
            } else {
7159
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7160
                if (d_ot == OT_QUAD) {
7161
                    gen_op_lds_T0_A0(OT_LONG + s->mem_index);
7162
                } else {
7163
                    gen_op_ld_T0_A0(OT_LONG + s->mem_index);
7164
                }
7165
                gen_op_mov_reg_T0(d_ot, reg);
7166
            }
7167
        } else
7168
#endif
7169
        {
7170
            int label1;
7171
            TCGv t0, t1, t2;
7172

    
7173
            if (!s->pe || s->vm86)
7174
                goto illegal_op;
7175
            t0 = tcg_temp_local_new();
7176
            t1 = tcg_temp_local_new();
7177
            t2 = tcg_temp_local_new();
7178
            ot = OT_WORD;
7179
            modrm = ldub_code(s->pc++);
7180
            reg = (modrm >> 3) & 7;
7181
            mod = (modrm >> 6) & 3;
7182
            rm = modrm & 7;
7183
            if (mod != 3) {
7184
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7185
                gen_op_ld_v(ot + s->mem_index, t0, cpu_A0);
7186
            } else {
7187
                gen_op_mov_v_reg(ot, t0, rm);
7188
            }
7189
            gen_op_mov_v_reg(ot, t1, reg);
7190
            tcg_gen_andi_tl(cpu_tmp0, t0, 3);
7191
            tcg_gen_andi_tl(t1, t1, 3);
7192
            tcg_gen_movi_tl(t2, 0);
7193
            label1 = gen_new_label();
7194
            tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, t1, label1);
7195
            tcg_gen_andi_tl(t0, t0, ~3);
7196
            tcg_gen_or_tl(t0, t0, t1);
7197
            tcg_gen_movi_tl(t2, CC_Z);
7198
            gen_set_label(label1);
7199
            if (mod != 3) {
7200
                gen_op_st_v(ot + s->mem_index, t0, cpu_A0);
7201
            } else {
7202
                gen_op_mov_reg_v(ot, rm, t0);
7203
            }
7204
            if (s->cc_op != CC_OP_DYNAMIC)
7205
                gen_op_set_cc_op(s->cc_op);
7206
            gen_compute_eflags(cpu_cc_src);
7207
            tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
7208
            tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
7209
            s->cc_op = CC_OP_EFLAGS;
7210
            tcg_temp_free(t0);
7211
            tcg_temp_free(t1);
7212
            tcg_temp_free(t2);
7213
        }
7214
        break;
7215
    case 0x102: /* lar */
7216
    case 0x103: /* lsl */
7217
        {
7218
            int label1;
7219
            TCGv t0;
7220
            if (!s->pe || s->vm86)
7221
                goto illegal_op;
7222
            ot = dflag ? OT_LONG : OT_WORD;
7223
            modrm = ldub_code(s->pc++);
7224
            reg = ((modrm >> 3) & 7) | rex_r;
7225
            gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
7226
            t0 = tcg_temp_local_new();
7227
            if (s->cc_op != CC_OP_DYNAMIC)
7228
                gen_op_set_cc_op(s->cc_op);
7229
            if (b == 0x102)
7230
                gen_helper_lar(t0, cpu_T[0]);
7231
            else
7232
                gen_helper_lsl(t0, cpu_T[0]);
7233
            tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
7234
            label1 = gen_new_label();
7235
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
7236
            gen_op_mov_reg_v(ot, reg, t0);
7237
            gen_set_label(label1);
7238
            s->cc_op = CC_OP_EFLAGS;
7239
            tcg_temp_free(t0);
7240
        }
7241
        break;
7242
    case 0x118:
7243
        modrm = ldub_code(s->pc++);
7244
        mod = (modrm >> 6) & 3;
7245
        op = (modrm >> 3) & 7;
7246
        switch(op) {
7247
        case 0: /* prefetchnta */
7248
        case 1: /* prefetchnt0 */
7249
        case 2: /* prefetchnt0 */
7250
        case 3: /* prefetchnt0 */
7251
            if (mod == 3)
7252
                goto illegal_op;
7253
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7254
            /* nothing more to do */
7255
            break;
7256
        default: /* nop (multi byte) */
7257
            gen_nop_modrm(s, modrm);
7258
            break;
7259
        }
7260
        break;
7261
    case 0x119 ... 0x11f: /* nop (multi byte) */
7262
        modrm = ldub_code(s->pc++);
7263
        gen_nop_modrm(s, modrm);
7264
        break;
7265
    case 0x120: /* mov reg, crN */
7266
    case 0x122: /* mov crN, reg */
7267
        if (s->cpl != 0) {
7268
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7269
        } else {
7270
            modrm = ldub_code(s->pc++);
7271
            if ((modrm & 0xc0) != 0xc0)
7272
                goto illegal_op;
7273
            rm = (modrm & 7) | REX_B(s);
7274
            reg = ((modrm >> 3) & 7) | rex_r;
7275
            if (CODE64(s))
7276
                ot = OT_QUAD;
7277
            else
7278
                ot = OT_LONG;
7279
            switch(reg) {
7280
            case 0:
7281
            case 2:
7282
            case 3:
7283
            case 4:
7284
            case 8:
7285
                if (s->cc_op != CC_OP_DYNAMIC)
7286
                    gen_op_set_cc_op(s->cc_op);
7287
                gen_jmp_im(pc_start - s->cs_base);
7288
                if (b & 2) {
7289
                    gen_op_mov_TN_reg(ot, 0, rm);
7290
                    gen_helper_write_crN(tcg_const_i32(reg), cpu_T[0]);
7291
                    gen_jmp_im(s->pc - s->cs_base);
7292
                    gen_eob(s);
7293
                } else {
7294
                    gen_helper_read_crN(cpu_T[0], tcg_const_i32(reg));
7295
                    gen_op_mov_reg_T0(ot, rm);
7296
                }
7297
                break;
7298
            default:
7299
                goto illegal_op;
7300
            }
7301
        }
7302
        break;
7303
    case 0x121: /* mov reg, drN */
7304
    case 0x123: /* mov drN, reg */
7305
        if (s->cpl != 0) {
7306
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7307
        } else {
7308
            modrm = ldub_code(s->pc++);
7309
            if ((modrm & 0xc0) != 0xc0)
7310
                goto illegal_op;
7311
            rm = (modrm & 7) | REX_B(s);
7312
            reg = ((modrm >> 3) & 7) | rex_r;
7313
            if (CODE64(s))
7314
                ot = OT_QUAD;
7315
            else
7316
                ot = OT_LONG;
7317
            /* XXX: do it dynamically with CR4.DE bit */
7318
            if (reg == 4 || reg == 5 || reg >= 8)
7319
                goto illegal_op;
7320
            if (b & 2) {
7321
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
7322
                gen_op_mov_TN_reg(ot, 0, rm);
7323
                gen_helper_movl_drN_T0(tcg_const_i32(reg), cpu_T[0]);
7324
                gen_jmp_im(s->pc - s->cs_base);
7325
                gen_eob(s);
7326
            } else {
7327
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
7328
                tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,dr[reg]));
7329
                gen_op_mov_reg_T0(ot, rm);
7330
            }
7331
        }
7332
        break;
7333
    case 0x106: /* clts */
7334
        if (s->cpl != 0) {
7335
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7336
        } else {
7337
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7338
            gen_helper_clts();
7339
            /* abort block because static cpu state changed */
7340
            gen_jmp_im(s->pc - s->cs_base);
7341
            gen_eob(s);
7342
        }
7343
        break;
7344
    /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7345
    case 0x1c3: /* MOVNTI reg, mem */
7346
        if (!(s->cpuid_features & CPUID_SSE2))
7347
            goto illegal_op;
7348
        ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
7349
        modrm = ldub_code(s->pc++);
7350
        mod = (modrm >> 6) & 3;
7351
        if (mod == 3)
7352
            goto illegal_op;
7353
        reg = ((modrm >> 3) & 7) | rex_r;
7354
        /* generate a generic store */
7355
        gen_ldst_modrm(s, modrm, ot, reg, 1);
7356
        break;
7357
    case 0x1ae:
7358
        modrm = ldub_code(s->pc++);
7359
        mod = (modrm >> 6) & 3;
7360
        op = (modrm >> 3) & 7;
7361
        switch(op) {
7362
        case 0: /* fxsave */
7363
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
7364
                (s->flags & HF_EM_MASK))
7365
                goto illegal_op;
7366
            if (s->flags & HF_TS_MASK) {
7367
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7368
                break;
7369
            }
7370
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7371
            if (s->cc_op != CC_OP_DYNAMIC)
7372
                gen_op_set_cc_op(s->cc_op);
7373
            gen_jmp_im(pc_start - s->cs_base);
7374
            gen_helper_fxsave(cpu_A0, tcg_const_i32((s->dflag == 2)));
7375
            break;
7376
        case 1: /* fxrstor */
7377
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
7378
                (s->flags & HF_EM_MASK))
7379
                goto illegal_op;
7380
            if (s->flags & HF_TS_MASK) {
7381
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7382
                break;
7383
            }
7384
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7385
            if (s->cc_op != CC_OP_DYNAMIC)
7386
                gen_op_set_cc_op(s->cc_op);
7387
            gen_jmp_im(pc_start - s->cs_base);
7388
            gen_helper_fxrstor(cpu_A0, tcg_const_i32((s->dflag == 2)));
7389
            break;
7390
        case 2: /* ldmxcsr */
7391
        case 3: /* stmxcsr */
7392
            if (s->flags & HF_TS_MASK) {
7393
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7394
                break;
7395
            }
7396
            if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
7397
                mod == 3)
7398
                goto illegal_op;
7399
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7400
            if (op == 2) {
7401
                gen_op_ld_T0_A0(OT_LONG + s->mem_index);
7402
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
7403
            } else {
7404
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
7405
                gen_op_st_T0_A0(OT_LONG + s->mem_index);
7406
            }
7407
            break;
7408
        case 5: /* lfence */
7409
        case 6: /* mfence */
7410
            if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE))
7411
                goto illegal_op;
7412
            break;
7413
        case 7: /* sfence / clflush */
7414
            if ((modrm & 0xc7) == 0xc0) {
7415
                /* sfence */
7416
                /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
7417
                if (!(s->cpuid_features & CPUID_SSE))
7418
                    goto illegal_op;
7419
            } else {
7420
                /* clflush */
7421
                if (!(s->cpuid_features & CPUID_CLFLUSH))
7422
                    goto illegal_op;
7423
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7424
            }
7425
            break;
7426
        default:
7427
            goto illegal_op;
7428
        }
7429
        break;
7430
    case 0x10d: /* 3DNow! prefetch(w) */
7431
        modrm = ldub_code(s->pc++);
7432
        mod = (modrm >> 6) & 3;
7433
        if (mod == 3)
7434
            goto illegal_op;
7435
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7436
        /* ignore for now */
7437
        break;
7438
    case 0x1aa: /* rsm */
7439
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
7440
        if (!(s->flags & HF_SMM_MASK))
7441
            goto illegal_op;
7442
        if (s->cc_op != CC_OP_DYNAMIC) {
7443
            gen_op_set_cc_op(s->cc_op);
7444
            s->cc_op = CC_OP_DYNAMIC;
7445
        }
7446
        gen_jmp_im(s->pc - s->cs_base);
7447
        gen_helper_rsm();
7448
        gen_eob(s);
7449
        break;
7450
    case 0x1b8: /* SSE4.2 popcnt */
7451
        if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
7452
             PREFIX_REPZ)
7453
            goto illegal_op;
7454
        if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
7455
            goto illegal_op;
7456

    
7457
        modrm = ldub_code(s->pc++);
7458
        reg = ((modrm >> 3) & 7);
7459

    
7460
        if (s->prefix & PREFIX_DATA)
7461
            ot = OT_WORD;
7462
        else if (s->dflag != 2)
7463
            ot = OT_LONG;
7464
        else
7465
            ot = OT_QUAD;
7466

    
7467
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
7468
        gen_helper_popcnt(cpu_T[0], cpu_T[0], tcg_const_i32(ot));
7469
        gen_op_mov_reg_T0(ot, reg);
7470

    
7471
        s->cc_op = CC_OP_EFLAGS;
7472
        break;
7473
    case 0x10e ... 0x10f:
7474
        /* 3DNow! instructions, ignore prefixes */
7475
        s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
7476
    case 0x110 ... 0x117:
7477
    case 0x128 ... 0x12f:
7478
    case 0x138 ... 0x13a:
7479
    case 0x150 ... 0x177:
7480
    case 0x17c ... 0x17f:
7481
    case 0x1c2:
7482
    case 0x1c4 ... 0x1c6:
7483
    case 0x1d0 ... 0x1fe:
7484
        gen_sse(s, b, pc_start, rex_r);
7485
        break;
7486
    default:
7487
        goto illegal_op;
7488
    }
7489
    /* lock generation */
7490
    if (s->prefix & PREFIX_LOCK)
7491
        gen_helper_unlock();
7492
    return s->pc;
7493
 illegal_op:
7494
    if (s->prefix & PREFIX_LOCK)
7495
        gen_helper_unlock();
7496
    /* XXX: ensure that no lock was generated */
7497
    gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
7498
    return s->pc;
7499
}
7500

    
7501
void optimize_flags_init(void)
7502
{
7503
#if TCG_TARGET_REG_BITS == 32
7504
    assert(sizeof(CCTable) == (1 << 3));
7505
#else
7506
    assert(sizeof(CCTable) == (1 << 4));
7507
#endif
7508
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
7509
    cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0,
7510
                                       offsetof(CPUState, cc_op), "cc_op");
7511
    cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_src),
7512
                                    "cc_src");
7513
    cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_dst),
7514
                                    "cc_dst");
7515
    cpu_cc_tmp = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_tmp),
7516
                                    "cc_tmp");
7517

    
7518
    /* register helpers */
7519
#define GEN_HELPER 2
7520
#include "helper.h"
7521
}
7522

    
7523
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
7524
   basic block 'tb'. If search_pc is TRUE, also generate PC
7525
   information for each intermediate instruction. */
7526
static inline void gen_intermediate_code_internal(CPUState *env,
7527
                                                  TranslationBlock *tb,
7528
                                                  int search_pc)
7529
{
7530
    DisasContext dc1, *dc = &dc1;
7531
    target_ulong pc_ptr;
7532
    uint16_t *gen_opc_end;
7533
    CPUBreakpoint *bp;
7534
    int j, lj, cflags;
7535
    uint64_t flags;
7536
    target_ulong pc_start;
7537
    target_ulong cs_base;
7538
    int num_insns;
7539
    int max_insns;
7540

    
7541
    /* generate intermediate code */
7542
    pc_start = tb->pc;
7543
    cs_base = tb->cs_base;
7544
    flags = tb->flags;
7545
    cflags = tb->cflags;
7546

    
7547
    dc->pe = (flags >> HF_PE_SHIFT) & 1;
7548
    dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
7549
    dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
7550
    dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
7551
    dc->f_st = 0;
7552
    dc->vm86 = (flags >> VM_SHIFT) & 1;
7553
    dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
7554
    dc->iopl = (flags >> IOPL_SHIFT) & 3;
7555
    dc->tf = (flags >> TF_SHIFT) & 1;
7556
    dc->singlestep_enabled = env->singlestep_enabled;
7557
    dc->cc_op = CC_OP_DYNAMIC;
7558
    dc->cs_base = cs_base;
7559
    dc->tb = tb;
7560
    dc->popl_esp_hack = 0;
7561
    /* select memory access functions */
7562
    dc->mem_index = 0;
7563
    if (flags & HF_SOFTMMU_MASK) {
7564
        if (dc->cpl == 3)
7565
            dc->mem_index = 2 * 4;
7566
        else
7567
            dc->mem_index = 1 * 4;
7568
    }
7569
    dc->cpuid_features = env->cpuid_features;
7570
    dc->cpuid_ext_features = env->cpuid_ext_features;
7571
    dc->cpuid_ext2_features = env->cpuid_ext2_features;
7572
    dc->cpuid_ext3_features = env->cpuid_ext3_features;
7573
#ifdef TARGET_X86_64
7574
    dc->lma = (flags >> HF_LMA_SHIFT) & 1;
7575
    dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
7576
#endif
7577
    dc->flags = flags;
7578
    dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
7579
                    (flags & HF_INHIBIT_IRQ_MASK)
7580
#ifndef CONFIG_SOFTMMU
7581
                    || (flags & HF_SOFTMMU_MASK)
7582
#endif
7583
                    );
7584
#if 0
7585
    /* check addseg logic */
7586
    if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
7587
        printf("ERROR addseg\n");
7588
#endif
7589

    
7590
    cpu_T[0] = tcg_temp_new();
7591
    cpu_T[1] = tcg_temp_new();
7592
    cpu_A0 = tcg_temp_new();
7593
    cpu_T3 = tcg_temp_new();
7594

    
7595
    cpu_tmp0 = tcg_temp_new();
7596
    cpu_tmp1_i64 = tcg_temp_new_i64();
7597
    cpu_tmp2_i32 = tcg_temp_new_i32();
7598
    cpu_tmp3_i32 = tcg_temp_new_i32();
7599
    cpu_tmp4 = tcg_temp_new();
7600
    cpu_tmp5 = tcg_temp_new();
7601
    cpu_tmp6 = tcg_temp_new();
7602
    cpu_ptr0 = tcg_temp_new_ptr();
7603
    cpu_ptr1 = tcg_temp_new_ptr();
7604

    
7605
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
7606

    
7607
    dc->is_jmp = DISAS_NEXT;
7608
    pc_ptr = pc_start;
7609
    lj = -1;
7610
    num_insns = 0;
7611
    max_insns = tb->cflags & CF_COUNT_MASK;
7612
    if (max_insns == 0)
7613
        max_insns = CF_COUNT_MASK;
7614

    
7615
    gen_icount_start();
7616
    for(;;) {
7617
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
7618
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
7619
                if (bp->pc == pc_ptr) {
7620
                    gen_debug(dc, pc_ptr - dc->cs_base);
7621
                    break;
7622
                }
7623
            }
7624
        }
7625
        if (search_pc) {
7626
            j = gen_opc_ptr - gen_opc_buf;
7627
            if (lj < j) {
7628
                lj++;
7629
                while (lj < j)
7630
                    gen_opc_instr_start[lj++] = 0;
7631
            }
7632
            gen_opc_pc[lj] = pc_ptr;
7633
            gen_opc_cc_op[lj] = dc->cc_op;
7634
            gen_opc_instr_start[lj] = 1;
7635
            gen_opc_icount[lj] = num_insns;
7636
        }
7637
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
7638
            gen_io_start();
7639

    
7640
        pc_ptr = disas_insn(dc, pc_ptr);
7641
        num_insns++;
7642
        /* stop translation if indicated */
7643
        if (dc->is_jmp)
7644
            break;
7645
        /* if single step mode, we generate only one instruction and
7646
           generate an exception */
7647
        /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
7648
           the flag and abort the translation to give the irqs a
7649
           change to be happen */
7650
        if (dc->tf || dc->singlestep_enabled ||
7651
            (flags & HF_INHIBIT_IRQ_MASK)) {
7652
            gen_jmp_im(pc_ptr - dc->cs_base);
7653
            gen_eob(dc);
7654
            break;
7655
        }
7656
        /* if too long translation, stop generation too */
7657
        if (gen_opc_ptr >= gen_opc_end ||
7658
            (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32) ||
7659
            num_insns >= max_insns) {
7660
            gen_jmp_im(pc_ptr - dc->cs_base);
7661
            gen_eob(dc);
7662
            break;
7663
        }
7664
    }
7665
    if (tb->cflags & CF_LAST_IO)
7666
        gen_io_end();
7667
    gen_icount_end(tb, num_insns);
7668
    *gen_opc_ptr = INDEX_op_end;
7669
    /* we don't forget to fill the last values */
7670
    if (search_pc) {
7671
        j = gen_opc_ptr - gen_opc_buf;
7672
        lj++;
7673
        while (lj <= j)
7674
            gen_opc_instr_start[lj++] = 0;
7675
    }
7676

    
7677
#ifdef DEBUG_DISAS
7678
    log_cpu_state_mask(CPU_LOG_TB_CPU, env, X86_DUMP_CCOP);
7679
    if (loglevel & CPU_LOG_TB_IN_ASM) {
7680
        int disas_flags;
7681
        qemu_log("----------------\n");
7682
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
7683
#ifdef TARGET_X86_64
7684
        if (dc->code64)
7685
            disas_flags = 2;
7686
        else
7687
#endif
7688
            disas_flags = !dc->code32;
7689
        log_target_disas(pc_start, pc_ptr - pc_start, disas_flags);
7690
        qemu_log("\n");
7691
    }
7692
#endif
7693

    
7694
    if (!search_pc) {
7695
        tb->size = pc_ptr - pc_start;
7696
        tb->icount = num_insns;
7697
    }
7698
}
7699

    
7700
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
7701
{
7702
    gen_intermediate_code_internal(env, tb, 0);
7703
}
7704

    
7705
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
7706
{
7707
    gen_intermediate_code_internal(env, tb, 1);
7708
}
7709

    
7710
void gen_pc_load(CPUState *env, TranslationBlock *tb,
7711
                unsigned long searched_pc, int pc_pos, void *puc)
7712
{
7713
    int cc_op;
7714
#ifdef DEBUG_DISAS
7715
    if (loglevel & CPU_LOG_TB_OP) {
7716
        int i;
7717
        qemu_log("RESTORE:\n");
7718
        for(i = 0;i <= pc_pos; i++) {
7719
            if (gen_opc_instr_start[i]) {
7720
                qemu_log("0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]);
7721
            }
7722
        }
7723
        qemu_log("spc=0x%08lx pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
7724
                searched_pc, pc_pos, gen_opc_pc[pc_pos] - tb->cs_base,
7725
                (uint32_t)tb->cs_base);
7726
    }
7727
#endif
7728
    env->eip = gen_opc_pc[pc_pos] - tb->cs_base;
7729
    cc_op = gen_opc_cc_op[pc_pos];
7730
    if (cc_op != CC_OP_DYNAMIC)
7731
        env->cc_op = cc_op;
7732
}