Statistics
| Branch: | Revision:

root / target-i386 / translate.c @ 81a97d9d

History | View | Annotate | Download (257.2 kB)

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

    
26
#include "cpu.h"
27
#include "exec-all.h"
28
#include "disas.h"
29
#include "tcg-op.h"
30

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

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

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

    
59
//#define MACRO_TEST   1
60

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

    
75
static uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
76

    
77
#include "gen-icount.h"
78

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
251
#ifdef TARGET_X86_64
252

    
253
#define NB_OP_SIZES 4
254

    
255
#else /* !TARGET_X86_64 */
256

    
257
#define NB_OP_SIZES 3
258

    
259
#endif /* !TARGET_X86_64 */
260

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

    
275
static inline void gen_op_mov_reg_v(int ot, int reg, TCGv t0)
276
{
277
    TCGv tmp;
278

    
279
    switch(ot) {
280
    case OT_BYTE:
281
        tmp = tcg_temp_new();
282
        tcg_gen_ext8u_tl(tmp, t0);
283
        if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
284
            tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xff);
285
            tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], tmp);
286
        } else {
287
            tcg_gen_shli_tl(tmp, tmp, 8);
288
            tcg_gen_andi_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], ~0xff00);
289
            tcg_gen_or_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], tmp);
290
        }
291
        tcg_temp_free(tmp);
292
        break;
293
    case OT_WORD:
294
        tmp = tcg_temp_new();
295
        tcg_gen_ext16u_tl(tmp, t0);
296
        tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff);
297
        tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], tmp);
298
        tcg_temp_free(tmp);
299
        break;
300
    default: /* XXX this shouldn't be reached;  abort? */
301
    case OT_LONG:
302
        /* For x86_64, this sets the higher half of register to zero.
303
           For i386, this is equivalent to a mov. */
304
        tcg_gen_ext32u_tl(cpu_regs[reg], t0);
305
        break;
306
#ifdef TARGET_X86_64
307
    case OT_QUAD:
308
        tcg_gen_mov_tl(cpu_regs[reg], t0);
309
        break;
310
#endif
311
    }
312
}
313

    
314
static inline void gen_op_mov_reg_T0(int ot, int reg)
315
{
316
    gen_op_mov_reg_v(ot, reg, cpu_T[0]);
317
}
318

    
319
static inline void gen_op_mov_reg_T1(int ot, int reg)
320
{
321
    gen_op_mov_reg_v(ot, reg, cpu_T[1]);
322
}
323

    
324
static inline void gen_op_mov_reg_A0(int size, int reg)
325
{
326
    TCGv tmp;
327

    
328
    switch(size) {
329
    case 0:
330
        tmp = tcg_temp_new();
331
        tcg_gen_ext16u_tl(tmp, cpu_A0);
332
        tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff);
333
        tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], tmp);
334
        tcg_temp_free(tmp);
335
        break;
336
    default: /* XXX this shouldn't be reached;  abort? */
337
    case 1:
338
        /* For x86_64, this sets the higher half of register to zero.
339
           For i386, this is equivalent to a mov. */
340
        tcg_gen_ext32u_tl(cpu_regs[reg], cpu_A0);
341
        break;
342
#ifdef TARGET_X86_64
343
    case 2:
344
        tcg_gen_mov_tl(cpu_regs[reg], cpu_A0);
345
        break;
346
#endif
347
    }
348
}
349

    
350
static inline void gen_op_mov_v_reg(int ot, TCGv t0, int reg)
351
{
352
    switch(ot) {
353
    case OT_BYTE:
354
        if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
355
            goto std_case;
356
        } else {
357
            tcg_gen_shri_tl(t0, cpu_regs[reg - 4], 8);
358
            tcg_gen_ext8u_tl(t0, t0);
359
        }
360
        break;
361
    default:
362
    std_case:
363
        tcg_gen_mov_tl(t0, cpu_regs[reg]);
364
        break;
365
    }
366
}
367

    
368
static inline void gen_op_mov_TN_reg(int ot, int t_index, int reg)
369
{
370
    gen_op_mov_v_reg(ot, cpu_T[t_index], reg);
371
}
372

    
373
static inline void gen_op_movl_A0_reg(int reg)
374
{
375
    tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
376
}
377

    
378
static inline void gen_op_addl_A0_im(int32_t val)
379
{
380
    tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
381
#ifdef TARGET_X86_64
382
    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
383
#endif
384
}
385

    
386
#ifdef TARGET_X86_64
387
static inline void gen_op_addq_A0_im(int64_t val)
388
{
389
    tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
390
}
391
#endif
392
    
393
static void gen_add_A0_im(DisasContext *s, int val)
394
{
395
#ifdef TARGET_X86_64
396
    if (CODE64(s))
397
        gen_op_addq_A0_im(val);
398
    else
399
#endif
400
        gen_op_addl_A0_im(val);
401
}
402

    
403
static inline void gen_op_addl_T0_T1(void)
404
{
405
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
406
}
407

    
408
static inline void gen_op_jmp_T0(void)
409
{
410
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, eip));
411
}
412

    
413
static inline void gen_op_add_reg_im(int size, int reg, int32_t val)
414
{
415
    switch(size) {
416
    case 0:
417
        tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
418
        tcg_gen_ext16u_tl(cpu_tmp0, cpu_tmp0);
419
        tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff);
420
        tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0);
421
        break;
422
    case 1:
423
        tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
424
        /* For x86_64, this sets the higher half of register to zero.
425
           For i386, this is equivalent to a nop. */
426
        tcg_gen_ext32u_tl(cpu_tmp0, cpu_tmp0);
427
        tcg_gen_mov_tl(cpu_regs[reg], cpu_tmp0);
428
        break;
429
#ifdef TARGET_X86_64
430
    case 2:
431
        tcg_gen_addi_tl(cpu_regs[reg], cpu_regs[reg], val);
432
        break;
433
#endif
434
    }
435
}
436

    
437
static inline void gen_op_add_reg_T0(int size, int reg)
438
{
439
    switch(size) {
440
    case 0:
441
        tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]);
442
        tcg_gen_ext16u_tl(cpu_tmp0, cpu_tmp0);
443
        tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff);
444
        tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0);
445
        break;
446
    case 1:
447
        tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]);
448
        /* For x86_64, this sets the higher half of register to zero.
449
           For i386, this is equivalent to a nop. */
450
        tcg_gen_ext32u_tl(cpu_tmp0, cpu_tmp0);
451
        tcg_gen_mov_tl(cpu_regs[reg], cpu_tmp0);
452
        break;
453
#ifdef TARGET_X86_64
454
    case 2:
455
        tcg_gen_add_tl(cpu_regs[reg], cpu_regs[reg], cpu_T[0]);
456
        break;
457
#endif
458
    }
459
}
460

    
461
static inline void gen_op_set_cc_op(int32_t val)
462
{
463
    tcg_gen_movi_i32(cpu_cc_op, val);
464
}
465

    
466
static inline void gen_op_addl_A0_reg_sN(int shift, int reg)
467
{
468
    tcg_gen_mov_tl(cpu_tmp0, cpu_regs[reg]);
469
    if (shift != 0)
470
        tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
471
    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
472
    /* For x86_64, this sets the higher half of register to zero.
473
       For i386, this is equivalent to a nop. */
474
    tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
475
}
476

    
477
static inline void gen_op_movl_A0_seg(int reg)
478
{
479
    tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUState, segs[reg].base) + REG_L_OFFSET);
480
}
481

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

    
491
#ifdef TARGET_X86_64
492
static inline void gen_op_movq_A0_seg(int reg)
493
{
494
    tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUState, segs[reg].base));
495
}
496

    
497
static inline void gen_op_addq_A0_seg(int reg)
498
{
499
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, segs[reg].base));
500
    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
501
}
502

    
503
static inline void gen_op_movq_A0_reg(int reg)
504
{
505
    tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
506
}
507

    
508
static inline void gen_op_addq_A0_reg_sN(int shift, int reg)
509
{
510
    tcg_gen_mov_tl(cpu_tmp0, cpu_regs[reg]);
511
    if (shift != 0)
512
        tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
513
    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
514
}
515
#endif
516

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

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

    
557
/* XXX: always use ldu or lds */
558
static inline void gen_op_ld_T0_A0(int idx)
559
{
560
    gen_op_ld_v(idx, cpu_T[0], cpu_A0);
561
}
562

    
563
static inline void gen_op_ldu_T0_A0(int idx)
564
{
565
    gen_op_ld_v(idx, cpu_T[0], cpu_A0);
566
}
567

    
568
static inline void gen_op_ld_T1_A0(int idx)
569
{
570
    gen_op_ld_v(idx, cpu_T[1], cpu_A0);
571
}
572

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

    
596
static inline void gen_op_st_T0_A0(int idx)
597
{
598
    gen_op_st_v(idx, cpu_T[0], cpu_A0);
599
}
600

    
601
static inline void gen_op_st_T1_A0(int idx)
602
{
603
    gen_op_st_v(idx, cpu_T[1], cpu_A0);
604
}
605

    
606
static inline void gen_jmp_im(target_ulong pc)
607
{
608
    tcg_gen_movi_tl(cpu_tmp0, pc);
609
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, eip));
610
}
611

    
612
static inline void gen_string_movl_A0_ESI(DisasContext *s)
613
{
614
    int override;
615

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

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

    
668
static inline void gen_op_movl_T0_Dshift(int ot) 
669
{
670
    tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUState, df));
671
    tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot);
672
};
673

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

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

    
708
static inline void gen_op_jnz_ecx(int size, int label1)
709
{
710
    tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
711
    gen_extu(size + 1, cpu_tmp0);
712
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
713
}
714

    
715
static inline void gen_op_jz_ecx(int size, int label1)
716
{
717
    tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
718
    gen_extu(size + 1, cpu_tmp0);
719
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
720
}
721

    
722
static void gen_helper_in_func(int ot, TCGv v, TCGv_i32 n)
723
{
724
    switch (ot) {
725
    case 0: gen_helper_inb(v, n); break;
726
    case 1: gen_helper_inw(v, n); break;
727
    case 2: gen_helper_inl(v, n); break;
728
    }
729

    
730
}
731

    
732
static void gen_helper_out_func(int ot, TCGv_i32 v, TCGv_i32 n)
733
{
734
    switch (ot) {
735
    case 0: gen_helper_outb(v, n); break;
736
    case 1: gen_helper_outw(v, n); break;
737
    case 2: gen_helper_outl(v, n); break;
738
    }
739

    
740
}
741

    
742
static void gen_check_io(DisasContext *s, int ot, target_ulong cur_eip,
743
                         uint32_t svm_flags)
744
{
745
    int state_saved;
746
    target_ulong next_eip;
747

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

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

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

    
794
static void gen_op_update1_cc(void)
795
{
796
    tcg_gen_discard_tl(cpu_cc_src);
797
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
798
}
799

    
800
static void gen_op_update2_cc(void)
801
{
802
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
803
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
804
}
805

    
806
static inline void gen_op_cmpl_T0_T1_cc(void)
807
{
808
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
809
    tcg_gen_sub_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
810
}
811

    
812
static inline void gen_op_testl_T0_T1_cc(void)
813
{
814
    tcg_gen_discard_tl(cpu_cc_src);
815
    tcg_gen_and_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
816
}
817

    
818
static void gen_op_update_neg_cc(void)
819
{
820
    tcg_gen_neg_tl(cpu_cc_src, cpu_T[0]);
821
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
822
}
823

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

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

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

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

    
908
        /* some jumps are easy to compute */
909
    case CC_OP_ADDB:
910
    case CC_OP_ADDW:
911
    case CC_OP_ADDL:
912
    case CC_OP_ADDQ:
913

    
914
    case CC_OP_LOGICB:
915
    case CC_OP_LOGICW:
916
    case CC_OP_LOGICL:
917
    case CC_OP_LOGICQ:
918

    
919
    case CC_OP_INCB:
920
    case CC_OP_INCW:
921
    case CC_OP_INCL:
922
    case CC_OP_INCQ:
923

    
924
    case CC_OP_DECB:
925
    case CC_OP_DECW:
926
    case CC_OP_DECL:
927
    case CC_OP_DECQ:
928

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

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

    
950
    inv = b & 1;
951
    jcc_op = (b >> 1) & 7;
952

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

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

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

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

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

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

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

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

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

    
1223
    gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
1224
    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
1225
    tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1226
    tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]);
1227
    gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
1228

    
1229
    gen_op_movl_T0_Dshift(ot);
1230
    gen_op_add_reg_T0(s->aflag, R_ESI);
1231
    if (use_icount)
1232
        gen_io_end();
1233
}
1234

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

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

    
1271
GEN_REPZ(movs)
1272
GEN_REPZ(stos)
1273
GEN_REPZ(lods)
1274
GEN_REPZ(ins)
1275
GEN_REPZ(outs)
1276
GEN_REPZ2(scas)
1277
GEN_REPZ2(cmps)
1278

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

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

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

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

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

    
1434
    if (ot == OT_QUAD)
1435
        mask = 0x3f;
1436
    else
1437
        mask = 0x1f;
1438

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

    
1445
    tcg_gen_andi_tl(cpu_T[1], cpu_T[1], mask);
1446

    
1447
    tcg_gen_addi_tl(cpu_tmp5, cpu_T[1], -1);
1448

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

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

    
1474
    /* XXX: inefficient */
1475
    t0 = tcg_temp_local_new();
1476
    t1 = tcg_temp_local_new();
1477

    
1478
    tcg_gen_mov_tl(t0, cpu_T[0]);
1479
    tcg_gen_mov_tl(t1, cpu_T3);
1480

    
1481
    shift_label = gen_new_label();
1482
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, shift_label);
1483

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

    
1494
    tcg_temp_free(t0);
1495
    tcg_temp_free(t1);
1496
}
1497

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

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

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

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

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

    
1557
static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, 
1558
                          int is_right)
1559
{
1560
    target_ulong mask;
1561
    int label1, label2, data_bits;
1562
    TCGv t0, t1, t2, a0;
1563

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

    
1570
    if (ot == OT_QUAD)
1571
        mask = 0x3f;
1572
    else
1573
        mask = 0x1f;
1574

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

    
1583
    tcg_gen_mov_tl(t1, cpu_T[1]);
1584

    
1585
    tcg_gen_andi_tl(t1, t1, mask);
1586

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

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

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

    
1626
    label2 = gen_new_label();
1627
    tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label2);
1628

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

    
1647
    tcg_temp_free(t0);
1648
    tcg_temp_free(t1);
1649
    tcg_temp_free(t2);
1650
    tcg_temp_free(a0);
1651
}
1652

    
1653
static void gen_rot_rm_im(DisasContext *s, int ot, int op1, int op2,
1654
                          int is_right)
1655
{
1656
    int mask;
1657
    int data_bits;
1658
    TCGv t0, t1, a0;
1659

    
1660
    /* XXX: inefficient, but we must use local temps */
1661
    t0 = tcg_temp_local_new();
1662
    t1 = tcg_temp_local_new();
1663
    a0 = tcg_temp_local_new();
1664

    
1665
    if (ot == OT_QUAD)
1666
        mask = 0x3f;
1667
    else
1668
        mask = 0x1f;
1669

    
1670
    /* load */
1671
    if (op1 == OR_TMP0) {
1672
        tcg_gen_mov_tl(a0, cpu_A0);
1673
        gen_op_ld_v(ot + s->mem_index, t0, a0);
1674
    } else {
1675
        gen_op_mov_v_reg(ot, t0, op1);
1676
    }
1677

    
1678
    gen_extu(ot, t0);
1679
    tcg_gen_mov_tl(t1, t0);
1680

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

    
1696
    /* store */
1697
    if (op1 == OR_TMP0) {
1698
        gen_op_st_v(ot + s->mem_index, t0, a0);
1699
    } else {
1700
        gen_op_mov_reg_v(ot, op1, t0);
1701
    }
1702

    
1703
    if (op2 != 0) {
1704
        /* update eflags */
1705
        if (s->cc_op != CC_OP_DYNAMIC)
1706
            gen_op_set_cc_op(s->cc_op);
1707

    
1708
        gen_compute_eflags(cpu_cc_src);
1709
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
1710
        tcg_gen_xor_tl(cpu_tmp0, t1, t0);
1711
        tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
1712
        tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
1713
        tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
1714
        if (is_right) {
1715
            tcg_gen_shri_tl(t0, t0, data_bits - 1);
1716
        }
1717
        tcg_gen_andi_tl(t0, t0, CC_C);
1718
        tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
1719

    
1720
        tcg_gen_discard_tl(cpu_cc_dst);
1721
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
1722
        s->cc_op = CC_OP_EFLAGS;
1723
    }
1724

    
1725
    tcg_temp_free(t0);
1726
    tcg_temp_free(t1);
1727
    tcg_temp_free(a0);
1728
}
1729

    
1730
/* XXX: add faster immediate = 1 case */
1731
static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, 
1732
                           int is_right)
1733
{
1734
    int label1;
1735

    
1736
    if (s->cc_op != CC_OP_DYNAMIC)
1737
        gen_op_set_cc_op(s->cc_op);
1738

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

    
1770
    /* update eflags */
1771
    label1 = gen_new_label();
1772
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cc_tmp, -1, label1);
1773

    
1774
    tcg_gen_mov_tl(cpu_cc_src, cpu_cc_tmp);
1775
    tcg_gen_discard_tl(cpu_cc_dst);
1776
    tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
1777
        
1778
    gen_set_label(label1);
1779
    s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1780
}
1781

    
1782
/* XXX: add faster immediate case */
1783
static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1, 
1784
                                int is_right)
1785
{
1786
    int label1, label2, data_bits;
1787
    target_ulong mask;
1788
    TCGv t0, t1, t2, a0;
1789

    
1790
    t0 = tcg_temp_local_new();
1791
    t1 = tcg_temp_local_new();
1792
    t2 = tcg_temp_local_new();
1793
    a0 = tcg_temp_local_new();
1794

    
1795
    if (ot == OT_QUAD)
1796
        mask = 0x3f;
1797
    else
1798
        mask = 0x1f;
1799

    
1800
    /* load */
1801
    if (op1 == OR_TMP0) {
1802
        tcg_gen_mov_tl(a0, cpu_A0);
1803
        gen_op_ld_v(ot + s->mem_index, t0, a0);
1804
    } else {
1805
        gen_op_mov_v_reg(ot, t0, op1);
1806
    }
1807

    
1808
    tcg_gen_andi_tl(cpu_T3, cpu_T3, mask);
1809

    
1810
    tcg_gen_mov_tl(t1, cpu_T[1]);
1811
    tcg_gen_mov_tl(t2, cpu_T3);
1812

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

    
1827
            tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
1828
            
1829
            /* only needed if count > 16, but a test would complicate */
1830
            tcg_gen_subfi_tl(cpu_tmp5, 32, t2);
1831
            tcg_gen_shl_tl(cpu_tmp0, t0, cpu_tmp5);
1832

    
1833
            tcg_gen_shr_tl(t0, t0, t2);
1834

    
1835
            tcg_gen_or_tl(t0, t0, cpu_tmp0);
1836
        } else {
1837
            /* XXX: not optimal */
1838
            tcg_gen_andi_tl(t0, t0, 0xffff);
1839
            tcg_gen_shli_tl(t1, t1, 16);
1840
            tcg_gen_or_tl(t1, t1, t0);
1841
            tcg_gen_ext32u_tl(t1, t1);
1842
            
1843
            tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
1844
            tcg_gen_subfi_tl(cpu_tmp0, 32, cpu_tmp5);
1845
            tcg_gen_shr_tl(cpu_tmp5, t1, cpu_tmp0);
1846
            tcg_gen_or_tl(cpu_tmp4, cpu_tmp4, cpu_tmp5);
1847

    
1848
            tcg_gen_shl_tl(t0, t0, t2);
1849
            tcg_gen_subfi_tl(cpu_tmp5, 32, t2);
1850
            tcg_gen_shr_tl(t1, t1, cpu_tmp5);
1851
            tcg_gen_or_tl(t0, t0, t1);
1852
        }
1853
    } else {
1854
        data_bits = 8 << ot;
1855
        if (is_right) {
1856
            if (ot == OT_LONG)
1857
                tcg_gen_ext32u_tl(t0, t0);
1858

    
1859
            tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
1860

    
1861
            tcg_gen_shr_tl(t0, t0, t2);
1862
            tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2);
1863
            tcg_gen_shl_tl(t1, t1, cpu_tmp5);
1864
            tcg_gen_or_tl(t0, t0, t1);
1865
            
1866
        } else {
1867
            if (ot == OT_LONG)
1868
                tcg_gen_ext32u_tl(t1, t1);
1869

    
1870
            tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
1871
            
1872
            tcg_gen_shl_tl(t0, t0, t2);
1873
            tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2);
1874
            tcg_gen_shr_tl(t1, t1, cpu_tmp5);
1875
            tcg_gen_or_tl(t0, t0, t1);
1876
        }
1877
    }
1878
    tcg_gen_mov_tl(t1, cpu_tmp4);
1879

    
1880
    gen_set_label(label1);
1881
    /* store */
1882
    if (op1 == OR_TMP0) {
1883
        gen_op_st_v(ot + s->mem_index, t0, a0);
1884
    } else {
1885
        gen_op_mov_reg_v(ot, op1, t0);
1886
    }
1887
    
1888
    /* update eflags */
1889
    if (s->cc_op != CC_OP_DYNAMIC)
1890
        gen_op_set_cc_op(s->cc_op);
1891

    
1892
    label2 = gen_new_label();
1893
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label2);
1894

    
1895
    tcg_gen_mov_tl(cpu_cc_src, t1);
1896
    tcg_gen_mov_tl(cpu_cc_dst, t0);
1897
    if (is_right) {
1898
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
1899
    } else {
1900
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
1901
    }
1902
    gen_set_label(label2);
1903
    s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1904

    
1905
    tcg_temp_free(t0);
1906
    tcg_temp_free(t1);
1907
    tcg_temp_free(t2);
1908
    tcg_temp_free(a0);
1909
}
1910

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

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

    
1968
static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr)
1969
{
1970
    target_long disp;
1971
    int havesib;
1972
    int base;
1973
    int index;
1974
    int scale;
1975
    int opreg;
1976
    int mod, rm, code, override, must_add_seg;
1977

    
1978
    override = s->override;
1979
    must_add_seg = s->addseg;
1980
    if (override >= 0)
1981
        must_add_seg = 1;
1982
    mod = (modrm >> 6) & 3;
1983
    rm = modrm & 7;
1984

    
1985
    if (s->aflag) {
1986

    
1987
        havesib = 0;
1988
        base = rm;
1989
        index = 0;
1990
        scale = 0;
1991

    
1992
        if (base == 4) {
1993
            havesib = 1;
1994
            code = ldub_code(s->pc++);
1995
            scale = (code >> 6) & 3;
1996
            index = ((code >> 3) & 7) | REX_X(s);
1997
            base = (code & 7);
1998
        }
1999
        base |= REX_B(s);
2000

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

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

    
2146
    opreg = OR_A0;
2147
    disp = 0;
2148
    *reg_ptr = opreg;
2149
    *offset_ptr = disp;
2150
}
2151

    
2152
static void gen_nop_modrm(DisasContext *s, int modrm)
2153
{
2154
    int mod, rm, base, code;
2155

    
2156
    mod = (modrm >> 6) & 3;
2157
    if (mod == 3)
2158
        return;
2159
    rm = modrm & 7;
2160

    
2161
    if (s->aflag) {
2162

    
2163
        base = rm;
2164

    
2165
        if (base == 4) {
2166
            code = ldub_code(s->pc++);
2167
            base = (code & 7);
2168
        }
2169

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

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

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

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

    
2256
static inline uint32_t insn_get(DisasContext *s, int ot)
2257
{
2258
    uint32_t ret;
2259

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

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

    
2286
static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
2287
{
2288
    TranslationBlock *tb;
2289
    target_ulong pc;
2290

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

    
2307
static inline void gen_jcc(DisasContext *s, int b,
2308
                           target_ulong val, target_ulong next_eip)
2309
{
2310
    int l1, l2, cc_op;
2311

    
2312
    cc_op = s->cc_op;
2313
    gen_update_cc_op(s);
2314
    if (s->jmp_opt) {
2315
        l1 = gen_new_label();
2316
        gen_jcc1(s, cc_op, b, l1);
2317
        
2318
        gen_goto_tb(s, 0, next_eip);
2319

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2733
static void gen_jmp(DisasContext *s, target_ulong eip)
2734
{
2735
    gen_jmp_tb(s, eip, 0);
2736
}
2737

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

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

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

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

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

    
2780
static inline void gen_op_movq(int d_offset, int s_offset)
2781
{
2782
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2783
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2784
}
2785

    
2786
static inline void gen_op_movl(int d_offset, int s_offset)
2787
{
2788
    tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
2789
    tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
2790
}
2791

    
2792
static inline void gen_op_movq_env_0(int d_offset)
2793
{
2794
    tcg_gen_movi_i64(cpu_tmp1_i64, 0);
2795
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2796
}
2797

    
2798
#define SSE_SPECIAL ((void *)1)
2799
#define SSE_DUMMY ((void *)2)
2800

    
2801
#define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2802
#define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2803
                     gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2804

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

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

    
2845
    [0xc2] = SSE_FOP(cmpeq),
2846
    [0xc6] = { gen_helper_shufps, gen_helper_shufpd },
2847

    
2848
    [0x38] = { SSE_SPECIAL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* SSSE3/SSE4 */
2849
    [0x3a] = { SSE_SPECIAL, SSE_SPECIAL }, /* SSSE3/SSE4 */
2850

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

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

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

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

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

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

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

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

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

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

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

    
3144
    modrm = ldub_code(s->pc++);
3145
    reg = ((modrm >> 3) & 7);
3146
    if (is_xmm)
3147
        reg |= rex_r;
3148
    mod = (modrm >> 6) & 3;
3149
    if (sse_op2 == SSE_SPECIAL) {
3150
        b |= (b1 << 8);
3151
        switch(b) {
3152
        case 0x0e7: /* movntq */
3153
            if (mod == 3)
3154
                goto illegal_op;
3155
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3156
            gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
3157
            break;
3158
        case 0x1e7: /* movntdq */
3159
        case 0x02b: /* movntps */
3160
        case 0x12b: /* movntps */
3161
            if (mod == 3)
3162
                goto illegal_op;
3163
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3164
            gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3165
            break;
3166
        case 0x3f0: /* lddqu */
3167
            if (mod == 3)
3168
                goto illegal_op;
3169
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3170
            gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3171
            break;
3172
        case 0x22b: /* movntss */
3173
        case 0x32b: /* movntsd */
3174
            if (mod == 3)
3175
                goto illegal_op;
3176
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3177
            if (b1 & 1) {
3178
                gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,
3179
                    xmm_regs[reg]));
3180
            } else {
3181
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
3182
                    xmm_regs[reg].XMM_L(0)));
3183
                gen_op_st_T0_A0(OT_LONG + s->mem_index);
3184
            }
3185
            break;
3186
        case 0x6e: /* movd mm, ea */
3187
#ifdef TARGET_X86_64
3188
            if (s->dflag == 2) {
3189
                gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
3190
                tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,fpregs[reg].mmx));
3191
            } else
3192
#endif
3193
            {
3194
                gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
3195
                tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
3196
                                 offsetof(CPUX86State,fpregs[reg].mmx));
3197
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3198
                gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32);
3199
            }
3200
            break;
3201
        case 0x16e: /* movd xmm, ea */
3202
#ifdef TARGET_X86_64
3203
            if (s->dflag == 2) {
3204
                gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
3205
                tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
3206
                                 offsetof(CPUX86State,xmm_regs[reg]));
3207
                gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T[0]);
3208
            } else
3209
#endif
3210
            {
3211
                gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
3212
                tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
3213
                                 offsetof(CPUX86State,xmm_regs[reg]));
3214
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3215
                gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32);
3216
            }
3217
            break;
3218
        case 0x6f: /* movq mm, ea */
3219
            if (mod != 3) {
3220
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3221
                gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
3222
            } else {
3223
                rm = (modrm & 7);
3224
                tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
3225
                               offsetof(CPUX86State,fpregs[rm].mmx));
3226
                tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
3227
                               offsetof(CPUX86State,fpregs[reg].mmx));
3228
            }
3229
            break;
3230
        case 0x010: /* movups */
3231
        case 0x110: /* movupd */
3232
        case 0x028: /* movaps */
3233
        case 0x128: /* movapd */
3234
        case 0x16f: /* movdqa xmm, ea */
3235
        case 0x26f: /* movdqu xmm, ea */
3236
            if (mod != 3) {
3237
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3238
                gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3239
            } else {
3240
                rm = (modrm & 7) | REX_B(s);
3241
                gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
3242
                            offsetof(CPUX86State,xmm_regs[rm]));
3243
            }
3244
            break;
3245
        case 0x210: /* movss xmm, ea */
3246
            if (mod != 3) {
3247
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3248
                gen_op_ld_T0_A0(OT_LONG + s->mem_index);
3249
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3250
                gen_op_movl_T0_0();
3251
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
3252
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
3253
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
3254
            } else {
3255
                rm = (modrm & 7) | REX_B(s);
3256
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
3257
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
3258
            }
3259
            break;
3260
        case 0x310: /* movsd xmm, ea */
3261
            if (mod != 3) {
3262
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3263
                gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3264
                gen_op_movl_T0_0();
3265
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
3266
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
3267
            } else {
3268
                rm = (modrm & 7) | REX_B(s);
3269
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3270
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3271
            }
3272
            break;
3273
        case 0x012: /* movlps */
3274
        case 0x112: /* movlpd */
3275
            if (mod != 3) {
3276
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3277
                gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3278
            } else {
3279
                /* movhlps */
3280
                rm = (modrm & 7) | REX_B(s);
3281
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3282
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
3283
            }
3284
            break;
3285
        case 0x212: /* movsldup */
3286
            if (mod != 3) {
3287
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3288
                gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3289
            } else {
3290
                rm = (modrm & 7) | REX_B(s);
3291
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
3292
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
3293
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
3294
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(2)));
3295
            }
3296
            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
3297
                        offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3298
            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
3299
                        offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
3300
            break;
3301
        case 0x312: /* movddup */
3302
            if (mod != 3) {
3303
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3304
                gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3305
            } else {
3306
                rm = (modrm & 7) | REX_B(s);
3307
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3308
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3309
            }
3310
            gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
3311
                        offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3312
            break;
3313
        case 0x016: /* movhps */
3314
        case 0x116: /* movhpd */
3315
            if (mod != 3) {
3316
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3317
                gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3318
            } else {
3319
                /* movlhps */
3320
                rm = (modrm & 7) | REX_B(s);
3321
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
3322
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3323
            }
3324
            break;
3325
        case 0x216: /* movshdup */
3326
            if (mod != 3) {
3327
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3328
                gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3329
            } else {
3330
                rm = (modrm & 7) | REX_B(s);
3331
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
3332
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(1)));
3333
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
3334
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(3)));
3335
            }
3336
            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
3337
                        offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
3338
            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
3339
                        offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
3340
            break;
3341
        case 0x178:
3342
        case 0x378:
3343
            {
3344
                int bit_index, field_length;
3345

    
3346
                if (b1 == 1 && reg != 0)
3347
                    goto illegal_op;
3348
                field_length = ldub_code(s->pc++) & 0x3F;
3349
                bit_index = ldub_code(s->pc++) & 0x3F;
3350
                tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3351
                    offsetof(CPUX86State,xmm_regs[reg]));
3352
                if (b1 == 1)
3353
                    gen_helper_extrq_i(cpu_ptr0, tcg_const_i32(bit_index),
3354
                        tcg_const_i32(field_length));
3355
                else
3356
                    gen_helper_insertq_i(cpu_ptr0, tcg_const_i32(bit_index),
3357
                        tcg_const_i32(field_length));
3358
            }
3359
            break;
3360
        case 0x7e: /* movd ea, mm */
3361
#ifdef TARGET_X86_64
3362
            if (s->dflag == 2) {
3363
                tcg_gen_ld_i64(cpu_T[0], cpu_env, 
3364
                               offsetof(CPUX86State,fpregs[reg].mmx));
3365
                gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1);
3366
            } else
3367
#endif
3368
            {
3369
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
3370
                                 offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0)));
3371
                gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
3372
            }
3373
            break;
3374
        case 0x17e: /* movd ea, xmm */
3375
#ifdef TARGET_X86_64
3376
            if (s->dflag == 2) {
3377
                tcg_gen_ld_i64(cpu_T[0], cpu_env, 
3378
                               offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3379
                gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1);
3380
            } else
3381
#endif
3382
            {
3383
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
3384
                                 offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3385
                gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
3386
            }
3387
            break;
3388
        case 0x27e: /* movq xmm, ea */
3389
            if (mod != 3) {
3390
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3391
                gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3392
            } else {
3393
                rm = (modrm & 7) | REX_B(s);
3394
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3395
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3396
            }
3397
            gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3398
            break;
3399
        case 0x7f: /* movq ea, mm */
3400
            if (mod != 3) {
3401
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3402
                gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
3403
            } else {
3404
                rm = (modrm & 7);
3405
                gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
3406
                            offsetof(CPUX86State,fpregs[reg].mmx));
3407
            }
3408
            break;
3409
        case 0x011: /* movups */
3410
        case 0x111: /* movupd */
3411
        case 0x029: /* movaps */
3412
        case 0x129: /* movapd */
3413
        case 0x17f: /* movdqa ea, xmm */
3414
        case 0x27f: /* movdqu ea, xmm */
3415
            if (mod != 3) {
3416
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3417
                gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3418
            } else {
3419
                rm = (modrm & 7) | REX_B(s);
3420
                gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
3421
                            offsetof(CPUX86State,xmm_regs[reg]));
3422
            }
3423
            break;
3424
        case 0x211: /* movss ea, xmm */
3425
            if (mod != 3) {
3426
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3427
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3428
                gen_op_st_T0_A0(OT_LONG + s->mem_index);
3429
            } else {
3430
                rm = (modrm & 7) | REX_B(s);
3431
                gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)),
3432
                            offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3433
            }
3434
            break;
3435
        case 0x311: /* movsd ea, xmm */
3436
            if (mod != 3) {
3437
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3438
                gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3439
            } else {
3440
                rm = (modrm & 7) | REX_B(s);
3441
                gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
3442
                            offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3443
            }
3444
            break;
3445
        case 0x013: /* movlps */
3446
        case 0x113: /* movlpd */
3447
            if (mod != 3) {
3448
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3449
                gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3450
            } else {
3451
                goto illegal_op;
3452
            }
3453
            break;
3454
        case 0x017: /* movhps */
3455
        case 0x117: /* movhpd */
3456
            if (mod != 3) {
3457
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3458
                gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3459
            } else {
3460
                goto illegal_op;
3461
            }
3462
            break;
3463
        case 0x71: /* shift mm, im */
3464
        case 0x72:
3465
        case 0x73:
3466
        case 0x171: /* shift xmm, im */
3467
        case 0x172:
3468
        case 0x173:
3469
            if (b1 >= 2) {
3470
                goto illegal_op;
3471
            }
3472
            val = ldub_code(s->pc++);
3473
            if (is_xmm) {
3474
                gen_op_movl_T0_im(val);
3475
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
3476
                gen_op_movl_T0_0();
3477
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(1)));
3478
                op1_offset = offsetof(CPUX86State,xmm_t0);
3479
            } else {
3480
                gen_op_movl_T0_im(val);
3481
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0)));
3482
                gen_op_movl_T0_0();
3483
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1)));
3484
                op1_offset = offsetof(CPUX86State,mmx_t0);
3485
            }
3486
            sse_op2 = sse_op_table2[((b - 1) & 3) * 8 + (((modrm >> 3)) & 7)][b1];
3487
            if (!sse_op2)
3488
                goto illegal_op;
3489
            if (is_xmm) {
3490
                rm = (modrm & 7) | REX_B(s);
3491
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3492
            } else {
3493
                rm = (modrm & 7);
3494
                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3495
            }
3496
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3497
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset);
3498
            ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
3499
            break;
3500
        case 0x050: /* movmskps */
3501
            rm = (modrm & 7) | REX_B(s);
3502
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
3503
                             offsetof(CPUX86State,xmm_regs[rm]));
3504
            gen_helper_movmskps(cpu_tmp2_i32, cpu_ptr0);
3505
            tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3506
            gen_op_mov_reg_T0(OT_LONG, reg);
3507
            break;
3508
        case 0x150: /* movmskpd */
3509
            rm = (modrm & 7) | REX_B(s);
3510
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
3511
                             offsetof(CPUX86State,xmm_regs[rm]));
3512
            gen_helper_movmskpd(cpu_tmp2_i32, cpu_ptr0);
3513
            tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3514
            gen_op_mov_reg_T0(OT_LONG, reg);
3515
            break;
3516
        case 0x02a: /* cvtpi2ps */
3517
        case 0x12a: /* cvtpi2pd */
3518
            gen_helper_enter_mmx();
3519
            if (mod != 3) {
3520
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3521
                op2_offset = offsetof(CPUX86State,mmx_t0);
3522
                gen_ldq_env_A0(s->mem_index, op2_offset);
3523
            } else {
3524
                rm = (modrm & 7);
3525
                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3526
            }
3527
            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3528
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3529
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3530
            switch(b >> 8) {
3531
            case 0x0:
3532
                gen_helper_cvtpi2ps(cpu_ptr0, cpu_ptr1);
3533
                break;
3534
            default:
3535
            case 0x1:
3536
                gen_helper_cvtpi2pd(cpu_ptr0, cpu_ptr1);
3537
                break;
3538
            }
3539
            break;
3540
        case 0x22a: /* cvtsi2ss */
3541
        case 0x32a: /* cvtsi2sd */
3542
            ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3543
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3544
            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3545
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3546
            sse_op2 = sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2)];
3547
            if (ot == OT_LONG) {
3548
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3549
                ((void (*)(TCGv_ptr, TCGv_i32))sse_op2)(cpu_ptr0, cpu_tmp2_i32);
3550
            } else {
3551
                ((void (*)(TCGv_ptr, TCGv))sse_op2)(cpu_ptr0, cpu_T[0]);
3552
            }
3553
            break;
3554
        case 0x02c: /* cvttps2pi */
3555
        case 0x12c: /* cvttpd2pi */
3556
        case 0x02d: /* cvtps2pi */
3557
        case 0x12d: /* cvtpd2pi */
3558
            gen_helper_enter_mmx();
3559
            if (mod != 3) {
3560
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3561
                op2_offset = offsetof(CPUX86State,xmm_t0);
3562
                gen_ldo_env_A0(s->mem_index, op2_offset);
3563
            } else {
3564
                rm = (modrm & 7) | REX_B(s);
3565
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3566
            }
3567
            op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
3568
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3569
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3570
            switch(b) {
3571
            case 0x02c:
3572
                gen_helper_cvttps2pi(cpu_ptr0, cpu_ptr1);
3573
                break;
3574
            case 0x12c:
3575
                gen_helper_cvttpd2pi(cpu_ptr0, cpu_ptr1);
3576
                break;
3577
            case 0x02d:
3578
                gen_helper_cvtps2pi(cpu_ptr0, cpu_ptr1);
3579
                break;
3580
            case 0x12d:
3581
                gen_helper_cvtpd2pi(cpu_ptr0, cpu_ptr1);
3582
                break;
3583
            }
3584
            break;
3585
        case 0x22c: /* cvttss2si */
3586
        case 0x32c: /* cvttsd2si */
3587
        case 0x22d: /* cvtss2si */
3588
        case 0x32d: /* cvtsd2si */
3589
            ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3590
            if (mod != 3) {
3591
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3592
                if ((b >> 8) & 1) {
3593
                    gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_Q(0)));
3594
                } else {
3595
                    gen_op_ld_T0_A0(OT_LONG + s->mem_index);
3596
                    tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
3597
                }
3598
                op2_offset = offsetof(CPUX86State,xmm_t0);
3599
            } else {
3600
                rm = (modrm & 7) | REX_B(s);
3601
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3602
            }
3603
            sse_op2 = sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2) + 4 +
3604
                                    (b & 1) * 4];
3605
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3606
            if (ot == OT_LONG) {
3607
                ((void (*)(TCGv_i32, TCGv_ptr))sse_op2)(cpu_tmp2_i32, cpu_ptr0);
3608
                tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3609
            } else {
3610
                ((void (*)(TCGv, TCGv_ptr))sse_op2)(cpu_T[0], cpu_ptr0);
3611
            }
3612
            gen_op_mov_reg_T0(ot, reg);
3613
            break;
3614
        case 0xc4: /* pinsrw */
3615
        case 0x1c4:
3616
            s->rip_offset = 1;
3617
            gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
3618
            val = ldub_code(s->pc++);
3619
            if (b1) {
3620
                val &= 7;
3621
                tcg_gen_st16_tl(cpu_T[0], cpu_env,
3622
                                offsetof(CPUX86State,xmm_regs[reg].XMM_W(val)));
3623
            } else {
3624
                val &= 3;
3625
                tcg_gen_st16_tl(cpu_T[0], cpu_env,
3626
                                offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val)));
3627
            }
3628
            break;
3629
        case 0xc5: /* pextrw */
3630
        case 0x1c5:
3631
            if (mod != 3)
3632
                goto illegal_op;
3633
            ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3634
            val = ldub_code(s->pc++);
3635
            if (b1) {
3636
                val &= 7;
3637
                rm = (modrm & 7) | REX_B(s);
3638
                tcg_gen_ld16u_tl(cpu_T[0], cpu_env,
3639
                                 offsetof(CPUX86State,xmm_regs[rm].XMM_W(val)));
3640
            } else {
3641
                val &= 3;
3642
                rm = (modrm & 7);
3643
                tcg_gen_ld16u_tl(cpu_T[0], cpu_env,
3644
                                offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
3645
            }
3646
            reg = ((modrm >> 3) & 7) | rex_r;
3647
            gen_op_mov_reg_T0(ot, reg);
3648
            break;
3649
        case 0x1d6: /* movq ea, xmm */
3650
            if (mod != 3) {
3651
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3652
                gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3653
            } else {
3654
                rm = (modrm & 7) | REX_B(s);
3655
                gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
3656
                            offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3657
                gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
3658
            }
3659
            break;
3660
        case 0x2d6: /* movq2dq */
3661
            gen_helper_enter_mmx();
3662
            rm = (modrm & 7);
3663
            gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3664
                        offsetof(CPUX86State,fpregs[rm].mmx));
3665
            gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3666
            break;
3667
        case 0x3d6: /* movdq2q */
3668
            gen_helper_enter_mmx();
3669
            rm = (modrm & 7) | REX_B(s);
3670
            gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
3671
                        offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3672
            break;
3673
        case 0xd7: /* pmovmskb */
3674
        case 0x1d7:
3675
            if (mod != 3)
3676
                goto illegal_op;
3677
            if (b1) {
3678
                rm = (modrm & 7) | REX_B(s);
3679
                tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm]));
3680
                gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_ptr0);
3681
            } else {
3682
                rm = (modrm & 7);
3683
                tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx));
3684
                gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_ptr0);
3685
            }
3686
            tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3687
            reg = ((modrm >> 3) & 7) | rex_r;
3688
            gen_op_mov_reg_T0(OT_LONG, reg);
3689
            break;
3690
        case 0x138:
3691
            if (s->prefix & PREFIX_REPNZ)
3692
                goto crc32;
3693
        case 0x038:
3694
            b = modrm;
3695
            modrm = ldub_code(s->pc++);
3696
            rm = modrm & 7;
3697
            reg = ((modrm >> 3) & 7) | rex_r;
3698
            mod = (modrm >> 6) & 3;
3699
            if (b1 >= 2) {
3700
                goto illegal_op;
3701
            }
3702

    
3703
            sse_op2 = sse_op_table6[b].op[b1];
3704
            if (!sse_op2)
3705
                goto illegal_op;
3706
            if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
3707
                goto illegal_op;
3708

    
3709
            if (b1) {
3710
                op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3711
                if (mod == 3) {
3712
                    op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
3713
                } else {
3714
                    op2_offset = offsetof(CPUX86State,xmm_t0);
3715
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3716
                    switch (b) {
3717
                    case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3718
                    case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3719
                    case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3720
                        gen_ldq_env_A0(s->mem_index, op2_offset +
3721
                                        offsetof(XMMReg, XMM_Q(0)));
3722
                        break;
3723
                    case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3724
                    case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3725
                        tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
3726
                                          (s->mem_index >> 2) - 1);
3727
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
3728
                        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset +
3729
                                        offsetof(XMMReg, XMM_L(0)));
3730
                        break;
3731
                    case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3732
                        tcg_gen_qemu_ld16u(cpu_tmp0, cpu_A0,
3733
                                          (s->mem_index >> 2) - 1);
3734
                        tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset +
3735
                                        offsetof(XMMReg, XMM_W(0)));
3736
                        break;
3737
                    case 0x2a:            /* movntqda */
3738
                        gen_ldo_env_A0(s->mem_index, op1_offset);
3739
                        return;
3740
                    default:
3741
                        gen_ldo_env_A0(s->mem_index, op2_offset);
3742
                    }
3743
                }
3744
            } else {
3745
                op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3746
                if (mod == 3) {
3747
                    op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3748
                } else {
3749
                    op2_offset = offsetof(CPUX86State,mmx_t0);
3750
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3751
                    gen_ldq_env_A0(s->mem_index, op2_offset);
3752
                }
3753
            }
3754
            if (sse_op2 == SSE_SPECIAL)
3755
                goto illegal_op;
3756

    
3757
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3758
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3759
            ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
3760

    
3761
            if (b == 0x17)
3762
                s->cc_op = CC_OP_EFLAGS;
3763
            break;
3764
        case 0x338: /* crc32 */
3765
        crc32:
3766
            b = modrm;
3767
            modrm = ldub_code(s->pc++);
3768
            reg = ((modrm >> 3) & 7) | rex_r;
3769

    
3770
            if (b != 0xf0 && b != 0xf1)
3771
                goto illegal_op;
3772
            if (!(s->cpuid_ext_features & CPUID_EXT_SSE42))
3773
                goto illegal_op;
3774

    
3775
            if (b == 0xf0)
3776
                ot = OT_BYTE;
3777
            else if (b == 0xf1 && s->dflag != 2)
3778
                if (s->prefix & PREFIX_DATA)
3779
                    ot = OT_WORD;
3780
                else
3781
                    ot = OT_LONG;
3782
            else
3783
                ot = OT_QUAD;
3784

    
3785
            gen_op_mov_TN_reg(OT_LONG, 0, reg);
3786
            tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3787
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3788
            gen_helper_crc32(cpu_T[0], cpu_tmp2_i32,
3789
                             cpu_T[0], tcg_const_i32(8 << ot));
3790

    
3791
            ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3792
            gen_op_mov_reg_T0(ot, reg);
3793
            break;
3794
        case 0x03a:
3795
        case 0x13a:
3796
            b = modrm;
3797
            modrm = ldub_code(s->pc++);
3798
            rm = modrm & 7;
3799
            reg = ((modrm >> 3) & 7) | rex_r;
3800
            mod = (modrm >> 6) & 3;
3801
            if (b1 >= 2) {
3802
                goto illegal_op;
3803
            }
3804

    
3805
            sse_op2 = sse_op_table7[b].op[b1];
3806
            if (!sse_op2)
3807
                goto illegal_op;
3808
            if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
3809
                goto illegal_op;
3810

    
3811
            if (sse_op2 == SSE_SPECIAL) {
3812
                ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3813
                rm = (modrm & 7) | REX_B(s);
3814
                if (mod != 3)
3815
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3816
                reg = ((modrm >> 3) & 7) | rex_r;
3817
                val = ldub_code(s->pc++);
3818
                switch (b) {
3819
                case 0x14: /* pextrb */
3820
                    tcg_gen_ld8u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
3821
                                            xmm_regs[reg].XMM_B(val & 15)));
3822
                    if (mod == 3)
3823
                        gen_op_mov_reg_T0(ot, rm);
3824
                    else
3825
                        tcg_gen_qemu_st8(cpu_T[0], cpu_A0,
3826
                                        (s->mem_index >> 2) - 1);
3827
                    break;
3828
                case 0x15: /* pextrw */
3829
                    tcg_gen_ld16u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
3830
                                            xmm_regs[reg].XMM_W(val & 7)));
3831
                    if (mod == 3)
3832
                        gen_op_mov_reg_T0(ot, rm);
3833
                    else
3834
                        tcg_gen_qemu_st16(cpu_T[0], cpu_A0,
3835
                                        (s->mem_index >> 2) - 1);
3836
                    break;
3837
                case 0x16:
3838
                    if (ot == OT_LONG) { /* pextrd */
3839
                        tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
3840
                                        offsetof(CPUX86State,
3841
                                                xmm_regs[reg].XMM_L(val & 3)));
3842
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3843
                        if (mod == 3)
3844
                            gen_op_mov_reg_v(ot, rm, cpu_T[0]);
3845
                        else
3846
                            tcg_gen_qemu_st32(cpu_T[0], cpu_A0,
3847
                                            (s->mem_index >> 2) - 1);
3848
                    } else { /* pextrq */
3849
#ifdef TARGET_X86_64
3850
                        tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
3851
                                        offsetof(CPUX86State,
3852
                                                xmm_regs[reg].XMM_Q(val & 1)));
3853
                        if (mod == 3)
3854
                            gen_op_mov_reg_v(ot, rm, cpu_tmp1_i64);
3855
                        else
3856
                            tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0,
3857
                                            (s->mem_index >> 2) - 1);
3858
#else
3859
                        goto illegal_op;
3860
#endif
3861
                    }
3862
                    break;
3863
                case 0x17: /* extractps */
3864
                    tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
3865
                                            xmm_regs[reg].XMM_L(val & 3)));
3866
                    if (mod == 3)
3867
                        gen_op_mov_reg_T0(ot, rm);
3868
                    else
3869
                        tcg_gen_qemu_st32(cpu_T[0], cpu_A0,
3870
                                        (s->mem_index >> 2) - 1);
3871
                    break;
3872
                case 0x20: /* pinsrb */
3873
                    if (mod == 3)
3874
                        gen_op_mov_TN_reg(OT_LONG, 0, rm);
3875
                    else
3876
                        tcg_gen_qemu_ld8u(cpu_tmp0, cpu_A0,
3877
                                        (s->mem_index >> 2) - 1);
3878
                    tcg_gen_st8_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State,
3879
                                            xmm_regs[reg].XMM_B(val & 15)));
3880
                    break;
3881
                case 0x21: /* insertps */
3882
                    if (mod == 3) {
3883
                        tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
3884
                                        offsetof(CPUX86State,xmm_regs[rm]
3885
                                                .XMM_L((val >> 6) & 3)));
3886
                    } else {
3887
                        tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
3888
                                        (s->mem_index >> 2) - 1);
3889
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
3890
                    }
3891
                    tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
3892
                                    offsetof(CPUX86State,xmm_regs[reg]
3893
                                            .XMM_L((val >> 4) & 3)));
3894
                    if ((val >> 0) & 1)
3895
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
3896
                                        cpu_env, offsetof(CPUX86State,
3897
                                                xmm_regs[reg].XMM_L(0)));
3898
                    if ((val >> 1) & 1)
3899
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
3900
                                        cpu_env, offsetof(CPUX86State,
3901
                                                xmm_regs[reg].XMM_L(1)));
3902
                    if ((val >> 2) & 1)
3903
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
3904
                                        cpu_env, offsetof(CPUX86State,
3905
                                                xmm_regs[reg].XMM_L(2)));
3906
                    if ((val >> 3) & 1)
3907
                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
3908
                                        cpu_env, offsetof(CPUX86State,
3909
                                                xmm_regs[reg].XMM_L(3)));
3910
                    break;
3911
                case 0x22:
3912
                    if (ot == OT_LONG) { /* pinsrd */
3913
                        if (mod == 3)
3914
                            gen_op_mov_v_reg(ot, cpu_tmp0, rm);
3915
                        else
3916
                            tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
3917
                                            (s->mem_index >> 2) - 1);
3918
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
3919
                        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
3920
                                        offsetof(CPUX86State,
3921
                                                xmm_regs[reg].XMM_L(val & 3)));
3922
                    } else { /* pinsrq */
3923
#ifdef TARGET_X86_64
3924
                        if (mod == 3)
3925
                            gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);
3926
                        else
3927
                            tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0,
3928
                                            (s->mem_index >> 2) - 1);
3929
                        tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
3930
                                        offsetof(CPUX86State,
3931
                                                xmm_regs[reg].XMM_Q(val & 1)));
3932
#else
3933
                        goto illegal_op;
3934
#endif
3935
                    }
3936
                    break;
3937
                }
3938
                return;
3939
            }
3940

    
3941
            if (b1) {
3942
                op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3943
                if (mod == 3) {
3944
                    op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
3945
                } else {
3946
                    op2_offset = offsetof(CPUX86State,xmm_t0);
3947
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3948
                    gen_ldo_env_A0(s->mem_index, op2_offset);
3949
                }
3950
            } else {
3951
                op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3952
                if (mod == 3) {
3953
                    op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3954
                } else {
3955
                    op2_offset = offsetof(CPUX86State,mmx_t0);
3956
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3957
                    gen_ldq_env_A0(s->mem_index, op2_offset);
3958
                }
3959
            }
3960
            val = ldub_code(s->pc++);
3961

    
3962
            if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
3963
                s->cc_op = CC_OP_EFLAGS;
3964

    
3965
                if (s->dflag == 2)
3966
                    /* The helper must use entire 64-bit gp registers */
3967
                    val |= 1 << 8;
3968
            }
3969

    
3970
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3971
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3972
            ((void (*)(TCGv_ptr, TCGv_ptr, TCGv_i32))sse_op2)(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
3973
            break;
3974
        default:
3975
            goto illegal_op;
3976
        }
3977
    } else {
3978
        /* generic MMX or SSE operation */
3979
        switch(b) {
3980
        case 0x70: /* pshufx insn */
3981
        case 0xc6: /* pshufx insn */
3982
        case 0xc2: /* compare insns */
3983
            s->rip_offset = 1;
3984
            break;
3985
        default:
3986
            break;
3987
        }
3988
        if (is_xmm) {
3989
            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3990
            if (mod != 3) {
3991
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3992
                op2_offset = offsetof(CPUX86State,xmm_t0);
3993
                if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f && b != 0x5b) ||
3994
                                b == 0xc2)) {
3995
                    /* specific case for SSE single instructions */
3996
                    if (b1 == 2) {
3997
                        /* 32 bit access */
3998
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
3999
                        tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
4000
                    } else {
4001
                        /* 64 bit access */
4002
                        gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_D(0)));
4003
                    }
4004
                } else {
4005
                    gen_ldo_env_A0(s->mem_index, op2_offset);
4006
                }
4007
            } else {
4008
                rm = (modrm & 7) | REX_B(s);
4009
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
4010
            }
4011
        } else {
4012
            op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4013
            if (mod != 3) {
4014
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4015
                op2_offset = offsetof(CPUX86State,mmx_t0);
4016
                gen_ldq_env_A0(s->mem_index, op2_offset);
4017
            } else {
4018
                rm = (modrm & 7);
4019
                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4020
            }
4021
        }
4022
        switch(b) {
4023
        case 0x0f: /* 3DNow! data insns */
4024
            if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
4025
                goto illegal_op;
4026
            val = ldub_code(s->pc++);
4027
            sse_op2 = sse_op_table5[val];
4028
            if (!sse_op2)
4029
                goto illegal_op;
4030
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4031
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4032
            ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
4033
            break;
4034
        case 0x70: /* pshufx insn */
4035
        case 0xc6: /* pshufx insn */
4036
            val = ldub_code(s->pc++);
4037
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4038
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4039
            ((void (*)(TCGv_ptr, TCGv_ptr, TCGv_i32))sse_op2)(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4040
            break;
4041
        case 0xc2:
4042
            /* compare insns */
4043
            val = ldub_code(s->pc++);
4044
            if (val >= 8)
4045
                goto illegal_op;
4046
            sse_op2 = sse_op_table4[val][b1];
4047
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4048
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4049
            ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
4050
            break;
4051
        case 0xf7:
4052
            /* maskmov : we must prepare A0 */
4053
            if (mod != 3)
4054
                goto illegal_op;
4055
#ifdef TARGET_X86_64
4056
            if (s->aflag == 2) {
4057
                gen_op_movq_A0_reg(R_EDI);
4058
            } else
4059
#endif
4060
            {
4061
                gen_op_movl_A0_reg(R_EDI);
4062
                if (s->aflag == 0)
4063
                    gen_op_andl_A0_ffff();
4064
            }
4065
            gen_add_A0_ds_seg(s);
4066

    
4067
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4068
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4069
            ((void (*)(TCGv_ptr, TCGv_ptr, TCGv))sse_op2)(cpu_ptr0, cpu_ptr1, cpu_A0);
4070
            break;
4071
        default:
4072
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4073
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4074
            ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
4075
            break;
4076
        }
4077
        if (b == 0x2e || b == 0x2f) {
4078
            s->cc_op = CC_OP_EFLAGS;
4079
        }
4080
    }
4081
}
4082

    
4083
/* convert one instruction. s->is_jmp is set if the translation must
4084
   be stopped. Return the next pc value */
4085
static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
4086
{
4087
    int b, prefixes, aflag, dflag;
4088
    int shift, ot;
4089
    int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
4090
    target_ulong next_eip, tval;
4091
    int rex_w, rex_r;
4092

    
4093
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
4094
        tcg_gen_debug_insn_start(pc_start);
4095
    s->pc = pc_start;
4096
    prefixes = 0;
4097
    aflag = s->code32;
4098
    dflag = s->code32;
4099
    s->override = -1;
4100
    rex_w = -1;
4101
    rex_r = 0;
4102
#ifdef TARGET_X86_64
4103
    s->rex_x = 0;
4104
    s->rex_b = 0;
4105
    x86_64_hregs = 0;
4106
#endif
4107
    s->rip_offset = 0; /* for relative ip address */
4108
 next_byte:
4109
    b = ldub_code(s->pc);
4110
    s->pc++;
4111
    /* check prefixes */
4112
#ifdef TARGET_X86_64
4113
    if (CODE64(s)) {
4114
        switch (b) {
4115
        case 0xf3:
4116
            prefixes |= PREFIX_REPZ;
4117
            goto next_byte;
4118
        case 0xf2:
4119
            prefixes |= PREFIX_REPNZ;
4120
            goto next_byte;
4121
        case 0xf0:
4122
            prefixes |= PREFIX_LOCK;
4123
            goto next_byte;
4124
        case 0x2e:
4125
            s->override = R_CS;
4126
            goto next_byte;
4127
        case 0x36:
4128
            s->override = R_SS;
4129
            goto next_byte;
4130
        case 0x3e:
4131
            s->override = R_DS;
4132
            goto next_byte;
4133
        case 0x26:
4134
            s->override = R_ES;
4135
            goto next_byte;
4136
        case 0x64:
4137
            s->override = R_FS;
4138
            goto next_byte;
4139
        case 0x65:
4140
            s->override = R_GS;
4141
            goto next_byte;
4142
        case 0x66:
4143
            prefixes |= PREFIX_DATA;
4144
            goto next_byte;
4145
        case 0x67:
4146
            prefixes |= PREFIX_ADR;
4147
            goto next_byte;
4148
        case 0x40 ... 0x4f:
4149
            /* REX prefix */
4150
            rex_w = (b >> 3) & 1;
4151
            rex_r = (b & 0x4) << 1;
4152
            s->rex_x = (b & 0x2) << 2;
4153
            REX_B(s) = (b & 0x1) << 3;
4154
            x86_64_hregs = 1; /* select uniform byte register addressing */
4155
            goto next_byte;
4156
        }
4157
        if (rex_w == 1) {
4158
            /* 0x66 is ignored if rex.w is set */
4159
            dflag = 2;
4160
        } else {
4161
            if (prefixes & PREFIX_DATA)
4162
                dflag ^= 1;
4163
        }
4164
        if (!(prefixes & PREFIX_ADR))
4165
            aflag = 2;
4166
    } else
4167
#endif
4168
    {
4169
        switch (b) {
4170
        case 0xf3:
4171
            prefixes |= PREFIX_REPZ;
4172
            goto next_byte;
4173
        case 0xf2:
4174
            prefixes |= PREFIX_REPNZ;
4175
            goto next_byte;
4176
        case 0xf0:
4177
            prefixes |= PREFIX_LOCK;
4178
            goto next_byte;
4179
        case 0x2e:
4180
            s->override = R_CS;
4181
            goto next_byte;
4182
        case 0x36:
4183
            s->override = R_SS;
4184
            goto next_byte;
4185
        case 0x3e:
4186
            s->override = R_DS;
4187
            goto next_byte;
4188
        case 0x26:
4189
            s->override = R_ES;
4190
            goto next_byte;
4191
        case 0x64:
4192
            s->override = R_FS;
4193
            goto next_byte;
4194
        case 0x65:
4195
            s->override = R_GS;
4196
            goto next_byte;
4197
        case 0x66:
4198
            prefixes |= PREFIX_DATA;
4199
            goto next_byte;
4200
        case 0x67:
4201
            prefixes |= PREFIX_ADR;
4202
            goto next_byte;
4203
        }
4204
        if (prefixes & PREFIX_DATA)
4205
            dflag ^= 1;
4206
        if (prefixes & PREFIX_ADR)
4207
            aflag ^= 1;
4208
    }
4209

    
4210
    s->prefix = prefixes;
4211
    s->aflag = aflag;
4212
    s->dflag = dflag;
4213

    
4214
    /* lock generation */
4215
    if (prefixes & PREFIX_LOCK)
4216
        gen_helper_lock();
4217

    
4218
    /* now check op code */
4219
 reswitch:
4220
    switch(b) {
4221
    case 0x0f:
4222
        /**************************/
4223
        /* extended op code */
4224
        b = ldub_code(s->pc++) | 0x100;
4225
        goto reswitch;
4226

    
4227
        /**************************/
4228
        /* arith & logic */
4229
    case 0x00 ... 0x05:
4230
    case 0x08 ... 0x0d:
4231
    case 0x10 ... 0x15:
4232
    case 0x18 ... 0x1d:
4233
    case 0x20 ... 0x25:
4234
    case 0x28 ... 0x2d:
4235
    case 0x30 ... 0x35:
4236
    case 0x38 ... 0x3d:
4237
        {
4238
            int op, f, val;
4239
            op = (b >> 3) & 7;
4240
            f = (b >> 1) & 3;
4241

    
4242
            if ((b & 1) == 0)
4243
                ot = OT_BYTE;
4244
            else
4245
                ot = dflag + OT_WORD;
4246

    
4247
            switch(f) {
4248
            case 0: /* OP Ev, Gv */
4249
                modrm = ldub_code(s->pc++);
4250
                reg = ((modrm >> 3) & 7) | rex_r;
4251
                mod = (modrm >> 6) & 3;
4252
                rm = (modrm & 7) | REX_B(s);
4253
                if (mod != 3) {
4254
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4255
                    opreg = OR_TMP0;
4256
                } else if (op == OP_XORL && rm == reg) {
4257
                xor_zero:
4258
                    /* xor reg, reg optimisation */
4259
                    gen_op_movl_T0_0();
4260
                    s->cc_op = CC_OP_LOGICB + ot;
4261
                    gen_op_mov_reg_T0(ot, reg);
4262
                    gen_op_update1_cc();
4263
                    break;
4264
                } else {
4265
                    opreg = rm;
4266
                }
4267
                gen_op_mov_TN_reg(ot, 1, reg);
4268
                gen_op(s, op, ot, opreg);
4269
                break;
4270
            case 1: /* OP Gv, Ev */
4271
                modrm = ldub_code(s->pc++);
4272
                mod = (modrm >> 6) & 3;
4273
                reg = ((modrm >> 3) & 7) | rex_r;
4274
                rm = (modrm & 7) | REX_B(s);
4275
                if (mod != 3) {
4276
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4277
                    gen_op_ld_T1_A0(ot + s->mem_index);
4278
                } else if (op == OP_XORL && rm == reg) {
4279
                    goto xor_zero;
4280
                } else {
4281
                    gen_op_mov_TN_reg(ot, 1, rm);
4282
                }
4283
                gen_op(s, op, ot, reg);
4284
                break;
4285
            case 2: /* OP A, Iv */
4286
                val = insn_get(s, ot);
4287
                gen_op_movl_T1_im(val);
4288
                gen_op(s, op, ot, OR_EAX);
4289
                break;
4290
            }
4291
        }
4292
        break;
4293

    
4294
    case 0x82:
4295
        if (CODE64(s))
4296
            goto illegal_op;
4297
    case 0x80: /* GRP1 */
4298
    case 0x81:
4299
    case 0x83:
4300
        {
4301
            int val;
4302

    
4303
            if ((b & 1) == 0)
4304
                ot = OT_BYTE;
4305
            else
4306
                ot = dflag + OT_WORD;
4307

    
4308
            modrm = ldub_code(s->pc++);
4309
            mod = (modrm >> 6) & 3;
4310
            rm = (modrm & 7) | REX_B(s);
4311
            op = (modrm >> 3) & 7;
4312

    
4313
            if (mod != 3) {
4314
                if (b == 0x83)
4315
                    s->rip_offset = 1;
4316
                else
4317
                    s->rip_offset = insn_const_size(ot);
4318
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4319
                opreg = OR_TMP0;
4320
            } else {
4321
                opreg = rm;
4322
            }
4323

    
4324
            switch(b) {
4325
            default:
4326
            case 0x80:
4327
            case 0x81:
4328
            case 0x82:
4329
                val = insn_get(s, ot);
4330
                break;
4331
            case 0x83:
4332
                val = (int8_t)insn_get(s, OT_BYTE);
4333
                break;
4334
            }
4335
            gen_op_movl_T1_im(val);
4336
            gen_op(s, op, ot, opreg);
4337
        }
4338
        break;
4339

    
4340
        /**************************/
4341
        /* inc, dec, and other misc arith */
4342
    case 0x40 ... 0x47: /* inc Gv */
4343
        ot = dflag ? OT_LONG : OT_WORD;
4344
        gen_inc(s, ot, OR_EAX + (b & 7), 1);
4345
        break;
4346
    case 0x48 ... 0x4f: /* dec Gv */
4347
        ot = dflag ? OT_LONG : OT_WORD;
4348
        gen_inc(s, ot, OR_EAX + (b & 7), -1);
4349
        break;
4350
    case 0xf6: /* GRP3 */
4351
    case 0xf7:
4352
        if ((b & 1) == 0)
4353
            ot = OT_BYTE;
4354
        else
4355
            ot = dflag + OT_WORD;
4356

    
4357
        modrm = ldub_code(s->pc++);
4358
        mod = (modrm >> 6) & 3;
4359
        rm = (modrm & 7) | REX_B(s);
4360
        op = (modrm >> 3) & 7;
4361
        if (mod != 3) {
4362
            if (op == 0)
4363
                s->rip_offset = insn_const_size(ot);
4364
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4365
            gen_op_ld_T0_A0(ot + s->mem_index);
4366
        } else {
4367
            gen_op_mov_TN_reg(ot, 0, rm);
4368
        }
4369

    
4370
        switch(op) {
4371
        case 0: /* test */
4372
            val = insn_get(s, ot);
4373
            gen_op_movl_T1_im(val);
4374
            gen_op_testl_T0_T1_cc();
4375
            s->cc_op = CC_OP_LOGICB + ot;
4376
            break;
4377
        case 2: /* not */
4378
            tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
4379
            if (mod != 3) {
4380
                gen_op_st_T0_A0(ot + s->mem_index);
4381
            } else {
4382
                gen_op_mov_reg_T0(ot, rm);
4383
            }
4384
            break;
4385
        case 3: /* neg */
4386
            tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
4387
            if (mod != 3) {
4388
                gen_op_st_T0_A0(ot + s->mem_index);
4389
            } else {
4390
                gen_op_mov_reg_T0(ot, rm);
4391
            }
4392
            gen_op_update_neg_cc();
4393
            s->cc_op = CC_OP_SUBB + ot;
4394
            break;
4395
        case 4: /* mul */
4396
            switch(ot) {
4397
            case OT_BYTE:
4398
                gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX);
4399
                tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
4400
                tcg_gen_ext8u_tl(cpu_T[1], cpu_T[1]);
4401
                /* XXX: use 32 bit mul which could be faster */
4402
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4403
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
4404
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4405
                tcg_gen_andi_tl(cpu_cc_src, cpu_T[0], 0xff00);
4406
                s->cc_op = CC_OP_MULB;
4407
                break;
4408
            case OT_WORD:
4409
                gen_op_mov_TN_reg(OT_WORD, 1, R_EAX);
4410
                tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
4411
                tcg_gen_ext16u_tl(cpu_T[1], cpu_T[1]);
4412
                /* XXX: use 32 bit mul which could be faster */
4413
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4414
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
4415
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4416
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
4417
                gen_op_mov_reg_T0(OT_WORD, R_EDX);
4418
                tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4419
                s->cc_op = CC_OP_MULW;
4420
                break;
4421
            default:
4422
            case OT_LONG:
4423
#ifdef TARGET_X86_64
4424
                gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4425
                tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
4426
                tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
4427
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4428
                gen_op_mov_reg_T0(OT_LONG, R_EAX);
4429
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4430
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
4431
                gen_op_mov_reg_T0(OT_LONG, R_EDX);
4432
                tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4433
#else
4434
                {
4435
                    TCGv_i64 t0, t1;
4436
                    t0 = tcg_temp_new_i64();
4437
                    t1 = tcg_temp_new_i64();
4438
                    gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4439
                    tcg_gen_extu_i32_i64(t0, cpu_T[0]);
4440
                    tcg_gen_extu_i32_i64(t1, cpu_T[1]);
4441
                    tcg_gen_mul_i64(t0, t0, t1);
4442
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4443
                    gen_op_mov_reg_T0(OT_LONG, R_EAX);
4444
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4445
                    tcg_gen_shri_i64(t0, t0, 32);
4446
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4447
                    gen_op_mov_reg_T0(OT_LONG, R_EDX);
4448
                    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4449
                }
4450
#endif
4451
                s->cc_op = CC_OP_MULL;
4452
                break;
4453
#ifdef TARGET_X86_64
4454
            case OT_QUAD:
4455
                gen_helper_mulq_EAX_T0(cpu_T[0]);
4456
                s->cc_op = CC_OP_MULQ;
4457
                break;
4458
#endif
4459
            }
4460
            break;
4461
        case 5: /* imul */
4462
            switch(ot) {
4463
            case OT_BYTE:
4464
                gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX);
4465
                tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
4466
                tcg_gen_ext8s_tl(cpu_T[1], cpu_T[1]);
4467
                /* XXX: use 32 bit mul which could be faster */
4468
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4469
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
4470
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4471
                tcg_gen_ext8s_tl(cpu_tmp0, cpu_T[0]);
4472
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4473
                s->cc_op = CC_OP_MULB;
4474
                break;
4475
            case OT_WORD:
4476
                gen_op_mov_TN_reg(OT_WORD, 1, R_EAX);
4477
                tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4478
                tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
4479
                /* XXX: use 32 bit mul which could be faster */
4480
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4481
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
4482
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4483
                tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
4484
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4485
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
4486
                gen_op_mov_reg_T0(OT_WORD, R_EDX);
4487
                s->cc_op = CC_OP_MULW;
4488
                break;
4489
            default:
4490
            case OT_LONG:
4491
#ifdef TARGET_X86_64
4492
                gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4493
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4494
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
4495
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4496
                gen_op_mov_reg_T0(OT_LONG, R_EAX);
4497
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4498
                tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
4499
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4500
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
4501
                gen_op_mov_reg_T0(OT_LONG, R_EDX);
4502
#else
4503
                {
4504
                    TCGv_i64 t0, t1;
4505
                    t0 = tcg_temp_new_i64();
4506
                    t1 = tcg_temp_new_i64();
4507
                    gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4508
                    tcg_gen_ext_i32_i64(t0, cpu_T[0]);
4509
                    tcg_gen_ext_i32_i64(t1, cpu_T[1]);
4510
                    tcg_gen_mul_i64(t0, t0, t1);
4511
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4512
                    gen_op_mov_reg_T0(OT_LONG, R_EAX);
4513
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4514
                    tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
4515
                    tcg_gen_shri_i64(t0, t0, 32);
4516
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4517
                    gen_op_mov_reg_T0(OT_LONG, R_EDX);
4518
                    tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4519
                }
4520
#endif
4521
                s->cc_op = CC_OP_MULL;
4522
                break;
4523
#ifdef TARGET_X86_64
4524
            case OT_QUAD:
4525
                gen_helper_imulq_EAX_T0(cpu_T[0]);
4526
                s->cc_op = CC_OP_MULQ;
4527
                break;
4528
#endif
4529
            }
4530
            break;
4531
        case 6: /* div */
4532
            switch(ot) {
4533
            case OT_BYTE:
4534
                gen_jmp_im(pc_start - s->cs_base);
4535
                gen_helper_divb_AL(cpu_T[0]);
4536
                break;
4537
            case OT_WORD:
4538
                gen_jmp_im(pc_start - s->cs_base);
4539
                gen_helper_divw_AX(cpu_T[0]);
4540
                break;
4541
            default:
4542
            case OT_LONG:
4543
                gen_jmp_im(pc_start - s->cs_base);
4544
                gen_helper_divl_EAX(cpu_T[0]);
4545
                break;
4546
#ifdef TARGET_X86_64
4547
            case OT_QUAD:
4548
                gen_jmp_im(pc_start - s->cs_base);
4549
                gen_helper_divq_EAX(cpu_T[0]);
4550
                break;
4551
#endif
4552
            }
4553
            break;
4554
        case 7: /* idiv */
4555
            switch(ot) {
4556
            case OT_BYTE:
4557
                gen_jmp_im(pc_start - s->cs_base);
4558
                gen_helper_idivb_AL(cpu_T[0]);
4559
                break;
4560
            case OT_WORD:
4561
                gen_jmp_im(pc_start - s->cs_base);
4562
                gen_helper_idivw_AX(cpu_T[0]);
4563
                break;
4564
            default:
4565
            case OT_LONG:
4566
                gen_jmp_im(pc_start - s->cs_base);
4567
                gen_helper_idivl_EAX(cpu_T[0]);
4568
                break;
4569
#ifdef TARGET_X86_64
4570
            case OT_QUAD:
4571
                gen_jmp_im(pc_start - s->cs_base);
4572
                gen_helper_idivq_EAX(cpu_T[0]);
4573
                break;
4574
#endif
4575
            }
4576
            break;
4577
        default:
4578
            goto illegal_op;
4579
        }
4580
        break;
4581

    
4582
    case 0xfe: /* GRP4 */
4583
    case 0xff: /* GRP5 */
4584
        if ((b & 1) == 0)
4585
            ot = OT_BYTE;
4586
        else
4587
            ot = dflag + OT_WORD;
4588

    
4589
        modrm = ldub_code(s->pc++);
4590
        mod = (modrm >> 6) & 3;
4591
        rm = (modrm & 7) | REX_B(s);
4592
        op = (modrm >> 3) & 7;
4593
        if (op >= 2 && b == 0xfe) {
4594
            goto illegal_op;
4595
        }
4596
        if (CODE64(s)) {
4597
            if (op == 2 || op == 4) {
4598
                /* operand size for jumps is 64 bit */
4599
                ot = OT_QUAD;
4600
            } else if (op == 3 || op == 5) {
4601
                ot = dflag ? OT_LONG + (rex_w == 1) : OT_WORD;
4602
            } else if (op == 6) {
4603
                /* default push size is 64 bit */
4604
                ot = dflag ? OT_QUAD : OT_WORD;
4605
            }
4606
        }
4607
        if (mod != 3) {
4608
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4609
            if (op >= 2 && op != 3 && op != 5)
4610
                gen_op_ld_T0_A0(ot + s->mem_index);
4611
        } else {
4612
            gen_op_mov_TN_reg(ot, 0, rm);
4613
        }
4614

    
4615
        switch(op) {
4616
        case 0: /* inc Ev */
4617
            if (mod != 3)
4618
                opreg = OR_TMP0;
4619
            else
4620
                opreg = rm;
4621
            gen_inc(s, ot, opreg, 1);
4622
            break;
4623
        case 1: /* dec Ev */
4624
            if (mod != 3)
4625
                opreg = OR_TMP0;
4626
            else
4627
                opreg = rm;
4628
            gen_inc(s, ot, opreg, -1);
4629
            break;
4630
        case 2: /* call Ev */
4631
            /* XXX: optimize if memory (no 'and' is necessary) */
4632
            if (s->dflag == 0)
4633
                gen_op_andl_T0_ffff();
4634
            next_eip = s->pc - s->cs_base;
4635
            gen_movtl_T1_im(next_eip);
4636
            gen_push_T1(s);
4637
            gen_op_jmp_T0();
4638
            gen_eob(s);
4639
            break;
4640
        case 3: /* lcall Ev */
4641
            gen_op_ld_T1_A0(ot + s->mem_index);
4642
            gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4643
            gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
4644
        do_lcall:
4645
            if (s->pe && !s->vm86) {
4646
                if (s->cc_op != CC_OP_DYNAMIC)
4647
                    gen_op_set_cc_op(s->cc_op);
4648
                gen_jmp_im(pc_start - s->cs_base);
4649
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4650
                gen_helper_lcall_protected(cpu_tmp2_i32, cpu_T[1],
4651
                                           tcg_const_i32(dflag), 
4652
                                           tcg_const_i32(s->pc - pc_start));
4653
            } else {
4654
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4655
                gen_helper_lcall_real(cpu_tmp2_i32, cpu_T[1],
4656
                                      tcg_const_i32(dflag), 
4657
                                      tcg_const_i32(s->pc - s->cs_base));
4658
            }
4659
            gen_eob(s);
4660
            break;
4661
        case 4: /* jmp Ev */
4662
            if (s->dflag == 0)
4663
                gen_op_andl_T0_ffff();
4664
            gen_op_jmp_T0();
4665
            gen_eob(s);
4666
            break;
4667
        case 5: /* ljmp Ev */
4668
            gen_op_ld_T1_A0(ot + s->mem_index);
4669
            gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4670
            gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
4671
        do_ljmp:
4672
            if (s->pe && !s->vm86) {
4673
                if (s->cc_op != CC_OP_DYNAMIC)
4674
                    gen_op_set_cc_op(s->cc_op);
4675
                gen_jmp_im(pc_start - s->cs_base);
4676
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4677
                gen_helper_ljmp_protected(cpu_tmp2_i32, cpu_T[1],
4678
                                          tcg_const_i32(s->pc - pc_start));
4679
            } else {
4680
                gen_op_movl_seg_T0_vm(R_CS);
4681
                gen_op_movl_T0_T1();
4682
                gen_op_jmp_T0();
4683
            }
4684
            gen_eob(s);
4685
            break;
4686
        case 6: /* push Ev */
4687
            gen_push_T0(s);
4688
            break;
4689
        default:
4690
            goto illegal_op;
4691
        }
4692
        break;
4693

    
4694
    case 0x84: /* test Ev, Gv */
4695
    case 0x85:
4696
        if ((b & 1) == 0)
4697
            ot = OT_BYTE;
4698
        else
4699
            ot = dflag + OT_WORD;
4700

    
4701
        modrm = ldub_code(s->pc++);
4702
        reg = ((modrm >> 3) & 7) | rex_r;
4703

    
4704
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
4705
        gen_op_mov_TN_reg(ot, 1, reg);
4706
        gen_op_testl_T0_T1_cc();
4707
        s->cc_op = CC_OP_LOGICB + ot;
4708
        break;
4709

    
4710
    case 0xa8: /* test eAX, Iv */
4711
    case 0xa9:
4712
        if ((b & 1) == 0)
4713
            ot = OT_BYTE;
4714
        else
4715
            ot = dflag + OT_WORD;
4716
        val = insn_get(s, ot);
4717

    
4718
        gen_op_mov_TN_reg(ot, 0, OR_EAX);
4719
        gen_op_movl_T1_im(val);
4720
        gen_op_testl_T0_T1_cc();
4721
        s->cc_op = CC_OP_LOGICB + ot;
4722
        break;
4723

    
4724
    case 0x98: /* CWDE/CBW */
4725
#ifdef TARGET_X86_64
4726
        if (dflag == 2) {
4727
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
4728
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4729
            gen_op_mov_reg_T0(OT_QUAD, R_EAX);
4730
        } else
4731
#endif
4732
        if (dflag == 1) {
4733
            gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
4734
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4735
            gen_op_mov_reg_T0(OT_LONG, R_EAX);
4736
        } else {
4737
            gen_op_mov_TN_reg(OT_BYTE, 0, R_EAX);
4738
            tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
4739
            gen_op_mov_reg_T0(OT_WORD, R_EAX);
4740
        }
4741
        break;
4742
    case 0x99: /* CDQ/CWD */
4743
#ifdef TARGET_X86_64
4744
        if (dflag == 2) {
4745
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
4746
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 63);
4747
            gen_op_mov_reg_T0(OT_QUAD, R_EDX);
4748
        } else
4749
#endif
4750
        if (dflag == 1) {
4751
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
4752
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4753
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 31);
4754
            gen_op_mov_reg_T0(OT_LONG, R_EDX);
4755
        } else {
4756
            gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
4757
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4758
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 15);
4759
            gen_op_mov_reg_T0(OT_WORD, R_EDX);
4760
        }
4761
        break;
4762
    case 0x1af: /* imul Gv, Ev */
4763
    case 0x69: /* imul Gv, Ev, I */
4764
    case 0x6b:
4765
        ot = dflag + OT_WORD;
4766
        modrm = ldub_code(s->pc++);
4767
        reg = ((modrm >> 3) & 7) | rex_r;
4768
        if (b == 0x69)
4769
            s->rip_offset = insn_const_size(ot);
4770
        else if (b == 0x6b)
4771
            s->rip_offset = 1;
4772
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
4773
        if (b == 0x69) {
4774
            val = insn_get(s, ot);
4775
            gen_op_movl_T1_im(val);
4776
        } else if (b == 0x6b) {
4777
            val = (int8_t)insn_get(s, OT_BYTE);
4778
            gen_op_movl_T1_im(val);
4779
        } else {
4780
            gen_op_mov_TN_reg(ot, 1, reg);
4781
        }
4782

    
4783
#ifdef TARGET_X86_64
4784
        if (ot == OT_QUAD) {
4785
            gen_helper_imulq_T0_T1(cpu_T[0], cpu_T[0], cpu_T[1]);
4786
        } else
4787
#endif
4788
        if (ot == OT_LONG) {
4789
#ifdef TARGET_X86_64
4790
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4791
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
4792
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4793
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4794
                tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
4795
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4796
#else
4797
                {
4798
                    TCGv_i64 t0, t1;
4799
                    t0 = tcg_temp_new_i64();
4800
                    t1 = tcg_temp_new_i64();
4801
                    tcg_gen_ext_i32_i64(t0, cpu_T[0]);
4802
                    tcg_gen_ext_i32_i64(t1, cpu_T[1]);
4803
                    tcg_gen_mul_i64(t0, t0, t1);
4804
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4805
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4806
                    tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
4807
                    tcg_gen_shri_i64(t0, t0, 32);
4808
                    tcg_gen_trunc_i64_i32(cpu_T[1], t0);
4809
                    tcg_gen_sub_tl(cpu_cc_src, cpu_T[1], cpu_tmp0);
4810
                }
4811
#endif
4812
        } else {
4813
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4814
            tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
4815
            /* XXX: use 32 bit mul which could be faster */
4816
            tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4817
            tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4818
            tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
4819
            tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4820
        }
4821
        gen_op_mov_reg_T0(ot, reg);
4822
        s->cc_op = CC_OP_MULB + ot;
4823
        break;
4824
    case 0x1c0:
4825
    case 0x1c1: /* xadd Ev, Gv */
4826
        if ((b & 1) == 0)
4827
            ot = OT_BYTE;
4828
        else
4829
            ot = dflag + OT_WORD;
4830
        modrm = ldub_code(s->pc++);
4831
        reg = ((modrm >> 3) & 7) | rex_r;
4832
        mod = (modrm >> 6) & 3;
4833
        if (mod == 3) {
4834
            rm = (modrm & 7) | REX_B(s);
4835
            gen_op_mov_TN_reg(ot, 0, reg);
4836
            gen_op_mov_TN_reg(ot, 1, rm);
4837
            gen_op_addl_T0_T1();
4838
            gen_op_mov_reg_T1(ot, reg);
4839
            gen_op_mov_reg_T0(ot, rm);
4840
        } else {
4841
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4842
            gen_op_mov_TN_reg(ot, 0, reg);
4843
            gen_op_ld_T1_A0(ot + s->mem_index);
4844
            gen_op_addl_T0_T1();
4845
            gen_op_st_T0_A0(ot + s->mem_index);
4846
            gen_op_mov_reg_T1(ot, reg);
4847
        }
4848
        gen_op_update2_cc();
4849
        s->cc_op = CC_OP_ADDB + ot;
4850
        break;
4851
    case 0x1b0:
4852
    case 0x1b1: /* cmpxchg Ev, Gv */
4853
        {
4854
            int label1, label2;
4855
            TCGv t0, t1, t2, a0;
4856

    
4857
            if ((b & 1) == 0)
4858
                ot = OT_BYTE;
4859
            else
4860
                ot = dflag + OT_WORD;
4861
            modrm = ldub_code(s->pc++);
4862
            reg = ((modrm >> 3) & 7) | rex_r;
4863
            mod = (modrm >> 6) & 3;
4864
            t0 = tcg_temp_local_new();
4865
            t1 = tcg_temp_local_new();
4866
            t2 = tcg_temp_local_new();
4867
            a0 = tcg_temp_local_new();
4868
            gen_op_mov_v_reg(ot, t1, reg);
4869
            if (mod == 3) {
4870
                rm = (modrm & 7) | REX_B(s);
4871
                gen_op_mov_v_reg(ot, t0, rm);
4872
            } else {
4873
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4874
                tcg_gen_mov_tl(a0, cpu_A0);
4875
                gen_op_ld_v(ot + s->mem_index, t0, a0);
4876
                rm = 0; /* avoid warning */
4877
            }
4878
            label1 = gen_new_label();
4879
            tcg_gen_sub_tl(t2, cpu_regs[R_EAX], t0);
4880
            gen_extu(ot, t2);
4881
            tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
4882
            if (mod == 3) {
4883
                label2 = gen_new_label();
4884
                gen_op_mov_reg_v(ot, R_EAX, t0);
4885
                tcg_gen_br(label2);
4886
                gen_set_label(label1);
4887
                gen_op_mov_reg_v(ot, rm, t1);
4888
                gen_set_label(label2);
4889
            } else {
4890
                tcg_gen_mov_tl(t1, t0);
4891
                gen_op_mov_reg_v(ot, R_EAX, t0);
4892
                gen_set_label(label1);
4893
                /* always store */
4894
                gen_op_st_v(ot + s->mem_index, t1, a0);
4895
            }
4896
            tcg_gen_mov_tl(cpu_cc_src, t0);
4897
            tcg_gen_mov_tl(cpu_cc_dst, t2);
4898
            s->cc_op = CC_OP_SUBB + ot;
4899
            tcg_temp_free(t0);
4900
            tcg_temp_free(t1);
4901
            tcg_temp_free(t2);
4902
            tcg_temp_free(a0);
4903
        }
4904
        break;
4905
    case 0x1c7: /* cmpxchg8b */
4906
        modrm = ldub_code(s->pc++);
4907
        mod = (modrm >> 6) & 3;
4908
        if ((mod == 3) || ((modrm & 0x38) != 0x8))
4909
            goto illegal_op;
4910
#ifdef TARGET_X86_64
4911
        if (dflag == 2) {
4912
            if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
4913
                goto illegal_op;
4914
            gen_jmp_im(pc_start - s->cs_base);
4915
            if (s->cc_op != CC_OP_DYNAMIC)
4916
                gen_op_set_cc_op(s->cc_op);
4917
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4918
            gen_helper_cmpxchg16b(cpu_A0);
4919
        } else
4920
#endif        
4921
        {
4922
            if (!(s->cpuid_features & CPUID_CX8))
4923
                goto illegal_op;
4924
            gen_jmp_im(pc_start - s->cs_base);
4925
            if (s->cc_op != CC_OP_DYNAMIC)
4926
                gen_op_set_cc_op(s->cc_op);
4927
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4928
            gen_helper_cmpxchg8b(cpu_A0);
4929
        }
4930
        s->cc_op = CC_OP_EFLAGS;
4931
        break;
4932

    
4933
        /**************************/
4934
        /* push/pop */
4935
    case 0x50 ... 0x57: /* push */
4936
        gen_op_mov_TN_reg(OT_LONG, 0, (b & 7) | REX_B(s));
4937
        gen_push_T0(s);
4938
        break;
4939
    case 0x58 ... 0x5f: /* pop */
4940
        if (CODE64(s)) {
4941
            ot = dflag ? OT_QUAD : OT_WORD;
4942
        } else {
4943
            ot = dflag + OT_WORD;
4944
        }
4945
        gen_pop_T0(s);
4946
        /* NOTE: order is important for pop %sp */
4947
        gen_pop_update(s);
4948
        gen_op_mov_reg_T0(ot, (b & 7) | REX_B(s));
4949
        break;
4950
    case 0x60: /* pusha */
4951
        if (CODE64(s))
4952
            goto illegal_op;
4953
        gen_pusha(s);
4954
        break;
4955
    case 0x61: /* popa */
4956
        if (CODE64(s))
4957
            goto illegal_op;
4958
        gen_popa(s);
4959
        break;
4960
    case 0x68: /* push Iv */
4961
    case 0x6a:
4962
        if (CODE64(s)) {
4963
            ot = dflag ? OT_QUAD : OT_WORD;
4964
        } else {
4965
            ot = dflag + OT_WORD;
4966
        }
4967
        if (b == 0x68)
4968
            val = insn_get(s, ot);
4969
        else
4970
            val = (int8_t)insn_get(s, OT_BYTE);
4971
        gen_op_movl_T0_im(val);
4972
        gen_push_T0(s);
4973
        break;
4974
    case 0x8f: /* pop Ev */
4975
        if (CODE64(s)) {
4976
            ot = dflag ? OT_QUAD : OT_WORD;
4977
        } else {
4978
            ot = dflag + OT_WORD;
4979
        }
4980
        modrm = ldub_code(s->pc++);
4981
        mod = (modrm >> 6) & 3;
4982
        gen_pop_T0(s);
4983
        if (mod == 3) {
4984
            /* NOTE: order is important for pop %sp */
4985
            gen_pop_update(s);
4986
            rm = (modrm & 7) | REX_B(s);
4987
            gen_op_mov_reg_T0(ot, rm);
4988
        } else {
4989
            /* NOTE: order is important too for MMU exceptions */
4990
            s->popl_esp_hack = 1 << ot;
4991
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
4992
            s->popl_esp_hack = 0;
4993
            gen_pop_update(s);
4994
        }
4995
        break;
4996
    case 0xc8: /* enter */
4997
        {
4998
            int level;
4999
            val = lduw_code(s->pc);
5000
            s->pc += 2;
5001
            level = ldub_code(s->pc++);
5002
            gen_enter(s, val, level);
5003
        }
5004
        break;
5005
    case 0xc9: /* leave */
5006
        /* XXX: exception not precise (ESP is updated before potential exception) */
5007
        if (CODE64(s)) {
5008
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EBP);
5009
            gen_op_mov_reg_T0(OT_QUAD, R_ESP);
5010
        } else if (s->ss32) {
5011
            gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
5012
            gen_op_mov_reg_T0(OT_LONG, R_ESP);
5013
        } else {
5014
            gen_op_mov_TN_reg(OT_WORD, 0, R_EBP);
5015
            gen_op_mov_reg_T0(OT_WORD, R_ESP);
5016
        }
5017
        gen_pop_T0(s);
5018
        if (CODE64(s)) {
5019
            ot = dflag ? OT_QUAD : OT_WORD;
5020
        } else {
5021
            ot = dflag + OT_WORD;
5022
        }
5023
        gen_op_mov_reg_T0(ot, R_EBP);
5024
        gen_pop_update(s);
5025
        break;
5026
    case 0x06: /* push es */
5027
    case 0x0e: /* push cs */
5028
    case 0x16: /* push ss */
5029
    case 0x1e: /* push ds */
5030
        if (CODE64(s))
5031
            goto illegal_op;
5032
        gen_op_movl_T0_seg(b >> 3);
5033
        gen_push_T0(s);
5034
        break;
5035
    case 0x1a0: /* push fs */
5036
    case 0x1a8: /* push gs */
5037
        gen_op_movl_T0_seg((b >> 3) & 7);
5038
        gen_push_T0(s);
5039
        break;
5040
    case 0x07: /* pop es */
5041
    case 0x17: /* pop ss */
5042
    case 0x1f: /* pop ds */
5043
        if (CODE64(s))
5044
            goto illegal_op;
5045
        reg = b >> 3;
5046
        gen_pop_T0(s);
5047
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
5048
        gen_pop_update(s);
5049
        if (reg == R_SS) {
5050
            /* if reg == SS, inhibit interrupts/trace. */
5051
            /* If several instructions disable interrupts, only the
5052
               _first_ does it */
5053
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
5054
                gen_helper_set_inhibit_irq();
5055
            s->tf = 0;
5056
        }
5057
        if (s->is_jmp) {
5058
            gen_jmp_im(s->pc - s->cs_base);
5059
            gen_eob(s);
5060
        }
5061
        break;
5062
    case 0x1a1: /* pop fs */
5063
    case 0x1a9: /* pop gs */
5064
        gen_pop_T0(s);
5065
        gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
5066
        gen_pop_update(s);
5067
        if (s->is_jmp) {
5068
            gen_jmp_im(s->pc - s->cs_base);
5069
            gen_eob(s);
5070
        }
5071
        break;
5072

    
5073
        /**************************/
5074
        /* mov */
5075
    case 0x88:
5076
    case 0x89: /* mov Gv, Ev */
5077
        if ((b & 1) == 0)
5078
            ot = OT_BYTE;
5079
        else
5080
            ot = dflag + OT_WORD;
5081
        modrm = ldub_code(s->pc++);
5082
        reg = ((modrm >> 3) & 7) | rex_r;
5083

    
5084
        /* generate a generic store */
5085
        gen_ldst_modrm(s, modrm, ot, reg, 1);
5086
        break;
5087
    case 0xc6:
5088
    case 0xc7: /* mov Ev, Iv */
5089
        if ((b & 1) == 0)
5090
            ot = OT_BYTE;
5091
        else
5092
            ot = dflag + OT_WORD;
5093
        modrm = ldub_code(s->pc++);
5094
        mod = (modrm >> 6) & 3;
5095
        if (mod != 3) {
5096
            s->rip_offset = insn_const_size(ot);
5097
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5098
        }
5099
        val = insn_get(s, ot);
5100
        gen_op_movl_T0_im(val);
5101
        if (mod != 3)
5102
            gen_op_st_T0_A0(ot + s->mem_index);
5103
        else
5104
            gen_op_mov_reg_T0(ot, (modrm & 7) | REX_B(s));
5105
        break;
5106
    case 0x8a:
5107
    case 0x8b: /* mov Ev, Gv */
5108
        if ((b & 1) == 0)
5109
            ot = OT_BYTE;
5110
        else
5111
            ot = OT_WORD + dflag;
5112
        modrm = ldub_code(s->pc++);
5113
        reg = ((modrm >> 3) & 7) | rex_r;
5114

    
5115
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
5116
        gen_op_mov_reg_T0(ot, reg);
5117
        break;
5118
    case 0x8e: /* mov seg, Gv */
5119
        modrm = ldub_code(s->pc++);
5120
        reg = (modrm >> 3) & 7;
5121
        if (reg >= 6 || reg == R_CS)
5122
            goto illegal_op;
5123
        gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
5124
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
5125
        if (reg == R_SS) {
5126
            /* if reg == SS, inhibit interrupts/trace */
5127
            /* If several instructions disable interrupts, only the
5128
               _first_ does it */
5129
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
5130
                gen_helper_set_inhibit_irq();
5131
            s->tf = 0;
5132
        }
5133
        if (s->is_jmp) {
5134
            gen_jmp_im(s->pc - s->cs_base);
5135
            gen_eob(s);
5136
        }
5137
        break;
5138
    case 0x8c: /* mov Gv, seg */
5139
        modrm = ldub_code(s->pc++);
5140
        reg = (modrm >> 3) & 7;
5141
        mod = (modrm >> 6) & 3;
5142
        if (reg >= 6)
5143
            goto illegal_op;
5144
        gen_op_movl_T0_seg(reg);
5145
        if (mod == 3)
5146
            ot = OT_WORD + dflag;
5147
        else
5148
            ot = OT_WORD;
5149
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
5150
        break;
5151

    
5152
    case 0x1b6: /* movzbS Gv, Eb */
5153
    case 0x1b7: /* movzwS Gv, Eb */
5154
    case 0x1be: /* movsbS Gv, Eb */
5155
    case 0x1bf: /* movswS Gv, Eb */
5156
        {
5157
            int d_ot;
5158
            /* d_ot is the size of destination */
5159
            d_ot = dflag + OT_WORD;
5160
            /* ot is the size of source */
5161
            ot = (b & 1) + OT_BYTE;
5162
            modrm = ldub_code(s->pc++);
5163
            reg = ((modrm >> 3) & 7) | rex_r;
5164
            mod = (modrm >> 6) & 3;
5165
            rm = (modrm & 7) | REX_B(s);
5166

    
5167
            if (mod == 3) {
5168
                gen_op_mov_TN_reg(ot, 0, rm);
5169
                switch(ot | (b & 8)) {
5170
                case OT_BYTE:
5171
                    tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
5172
                    break;
5173
                case OT_BYTE | 8:
5174
                    tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
5175
                    break;
5176
                case OT_WORD:
5177
                    tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
5178
                    break;
5179
                default:
5180
                case OT_WORD | 8:
5181
                    tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
5182
                    break;
5183
                }
5184
                gen_op_mov_reg_T0(d_ot, reg);
5185
            } else {
5186
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5187
                if (b & 8) {
5188
                    gen_op_lds_T0_A0(ot + s->mem_index);
5189
                } else {
5190
                    gen_op_ldu_T0_A0(ot + s->mem_index);
5191
                }
5192
                gen_op_mov_reg_T0(d_ot, reg);
5193
            }
5194
        }
5195
        break;
5196

    
5197
    case 0x8d: /* lea */
5198
        ot = dflag + OT_WORD;
5199
        modrm = ldub_code(s->pc++);
5200
        mod = (modrm >> 6) & 3;
5201
        if (mod == 3)
5202
            goto illegal_op;
5203
        reg = ((modrm >> 3) & 7) | rex_r;
5204
        /* we must ensure that no segment is added */
5205
        s->override = -1;
5206
        val = s->addseg;
5207
        s->addseg = 0;
5208
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5209
        s->addseg = val;
5210
        gen_op_mov_reg_A0(ot - OT_WORD, reg);
5211
        break;
5212

    
5213
    case 0xa0: /* mov EAX, Ov */
5214
    case 0xa1:
5215
    case 0xa2: /* mov Ov, EAX */
5216
    case 0xa3:
5217
        {
5218
            target_ulong offset_addr;
5219

    
5220
            if ((b & 1) == 0)
5221
                ot = OT_BYTE;
5222
            else
5223
                ot = dflag + OT_WORD;
5224
#ifdef TARGET_X86_64
5225
            if (s->aflag == 2) {
5226
                offset_addr = ldq_code(s->pc);
5227
                s->pc += 8;
5228
                gen_op_movq_A0_im(offset_addr);
5229
            } else
5230
#endif
5231
            {
5232
                if (s->aflag) {
5233
                    offset_addr = insn_get(s, OT_LONG);
5234
                } else {
5235
                    offset_addr = insn_get(s, OT_WORD);
5236
                }
5237
                gen_op_movl_A0_im(offset_addr);
5238
            }
5239
            gen_add_A0_ds_seg(s);
5240
            if ((b & 2) == 0) {
5241
                gen_op_ld_T0_A0(ot + s->mem_index);
5242
                gen_op_mov_reg_T0(ot, R_EAX);
5243
            } else {
5244
                gen_op_mov_TN_reg(ot, 0, R_EAX);
5245
                gen_op_st_T0_A0(ot + s->mem_index);
5246
            }
5247
        }
5248
        break;
5249
    case 0xd7: /* xlat */
5250
#ifdef TARGET_X86_64
5251
        if (s->aflag == 2) {
5252
            gen_op_movq_A0_reg(R_EBX);
5253
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
5254
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
5255
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
5256
        } else
5257
#endif
5258
        {
5259
            gen_op_movl_A0_reg(R_EBX);
5260
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
5261
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
5262
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
5263
            if (s->aflag == 0)
5264
                gen_op_andl_A0_ffff();
5265
            else
5266
                tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
5267
        }
5268
        gen_add_A0_ds_seg(s);
5269
        gen_op_ldu_T0_A0(OT_BYTE + s->mem_index);
5270
        gen_op_mov_reg_T0(OT_BYTE, R_EAX);
5271
        break;
5272
    case 0xb0 ... 0xb7: /* mov R, Ib */
5273
        val = insn_get(s, OT_BYTE);
5274
        gen_op_movl_T0_im(val);
5275
        gen_op_mov_reg_T0(OT_BYTE, (b & 7) | REX_B(s));
5276
        break;
5277
    case 0xb8 ... 0xbf: /* mov R, Iv */
5278
#ifdef TARGET_X86_64
5279
        if (dflag == 2) {
5280
            uint64_t tmp;
5281
            /* 64 bit case */
5282
            tmp = ldq_code(s->pc);
5283
            s->pc += 8;
5284
            reg = (b & 7) | REX_B(s);
5285
            gen_movtl_T0_im(tmp);
5286
            gen_op_mov_reg_T0(OT_QUAD, reg);
5287
        } else
5288
#endif
5289
        {
5290
            ot = dflag ? OT_LONG : OT_WORD;
5291
            val = insn_get(s, ot);
5292
            reg = (b & 7) | REX_B(s);
5293
            gen_op_movl_T0_im(val);
5294
            gen_op_mov_reg_T0(ot, reg);
5295
        }
5296
        break;
5297

    
5298
    case 0x91 ... 0x97: /* xchg R, EAX */
5299
    do_xchg_reg_eax:
5300
        ot = dflag + OT_WORD;
5301
        reg = (b & 7) | REX_B(s);
5302
        rm = R_EAX;
5303
        goto do_xchg_reg;
5304
    case 0x86:
5305
    case 0x87: /* xchg Ev, Gv */
5306
        if ((b & 1) == 0)
5307
            ot = OT_BYTE;
5308
        else
5309
            ot = dflag + OT_WORD;
5310
        modrm = ldub_code(s->pc++);
5311
        reg = ((modrm >> 3) & 7) | rex_r;
5312
        mod = (modrm >> 6) & 3;
5313
        if (mod == 3) {
5314
            rm = (modrm & 7) | REX_B(s);
5315
        do_xchg_reg:
5316
            gen_op_mov_TN_reg(ot, 0, reg);
5317
            gen_op_mov_TN_reg(ot, 1, rm);
5318
            gen_op_mov_reg_T0(ot, rm);
5319
            gen_op_mov_reg_T1(ot, reg);
5320
        } else {
5321
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5322
            gen_op_mov_TN_reg(ot, 0, reg);
5323
            /* for xchg, lock is implicit */
5324
            if (!(prefixes & PREFIX_LOCK))
5325
                gen_helper_lock();
5326
            gen_op_ld_T1_A0(ot + s->mem_index);
5327
            gen_op_st_T0_A0(ot + s->mem_index);
5328
            if (!(prefixes & PREFIX_LOCK))
5329
                gen_helper_unlock();
5330
            gen_op_mov_reg_T1(ot, reg);
5331
        }
5332
        break;
5333
    case 0xc4: /* les Gv */
5334
        if (CODE64(s))
5335
            goto illegal_op;
5336
        op = R_ES;
5337
        goto do_lxx;
5338
    case 0xc5: /* lds Gv */
5339
        if (CODE64(s))
5340
            goto illegal_op;
5341
        op = R_DS;
5342
        goto do_lxx;
5343
    case 0x1b2: /* lss Gv */
5344
        op = R_SS;
5345
        goto do_lxx;
5346
    case 0x1b4: /* lfs Gv */
5347
        op = R_FS;
5348
        goto do_lxx;
5349
    case 0x1b5: /* lgs Gv */
5350
        op = R_GS;
5351
    do_lxx:
5352
        ot = dflag ? OT_LONG : OT_WORD;
5353
        modrm = ldub_code(s->pc++);
5354
        reg = ((modrm >> 3) & 7) | rex_r;
5355
        mod = (modrm >> 6) & 3;
5356
        if (mod == 3)
5357
            goto illegal_op;
5358
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5359
        gen_op_ld_T1_A0(ot + s->mem_index);
5360
        gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
5361
        /* load the segment first to handle exceptions properly */
5362
        gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
5363
        gen_movl_seg_T0(s, op, pc_start - s->cs_base);
5364
        /* then put the data */
5365
        gen_op_mov_reg_T1(ot, reg);
5366
        if (s->is_jmp) {
5367
            gen_jmp_im(s->pc - s->cs_base);
5368
            gen_eob(s);
5369
        }
5370
        break;
5371

    
5372
        /************************/
5373
        /* shifts */
5374
    case 0xc0:
5375
    case 0xc1:
5376
        /* shift Ev,Ib */
5377
        shift = 2;
5378
    grp2:
5379
        {
5380
            if ((b & 1) == 0)
5381
                ot = OT_BYTE;
5382
            else
5383
                ot = dflag + OT_WORD;
5384

    
5385
            modrm = ldub_code(s->pc++);
5386
            mod = (modrm >> 6) & 3;
5387
            op = (modrm >> 3) & 7;
5388

    
5389
            if (mod != 3) {
5390
                if (shift == 2) {
5391
                    s->rip_offset = 1;
5392
                }
5393
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5394
                opreg = OR_TMP0;
5395
            } else {
5396
                opreg = (modrm & 7) | REX_B(s);
5397
            }
5398

    
5399
            /* simpler op */
5400
            if (shift == 0) {
5401
                gen_shift(s, op, ot, opreg, OR_ECX);
5402
            } else {
5403
                if (shift == 2) {
5404
                    shift = ldub_code(s->pc++);
5405
                }
5406
                gen_shifti(s, op, ot, opreg, shift);
5407
            }
5408
        }
5409
        break;
5410
    case 0xd0:
5411
    case 0xd1:
5412
        /* shift Ev,1 */
5413
        shift = 1;
5414
        goto grp2;
5415
    case 0xd2:
5416
    case 0xd3:
5417
        /* shift Ev,cl */
5418
        shift = 0;
5419
        goto grp2;
5420

    
5421
    case 0x1a4: /* shld imm */
5422
        op = 0;
5423
        shift = 1;
5424
        goto do_shiftd;
5425
    case 0x1a5: /* shld cl */
5426
        op = 0;
5427
        shift = 0;
5428
        goto do_shiftd;
5429
    case 0x1ac: /* shrd imm */
5430
        op = 1;
5431
        shift = 1;
5432
        goto do_shiftd;
5433
    case 0x1ad: /* shrd cl */
5434
        op = 1;
5435
        shift = 0;
5436
    do_shiftd:
5437
        ot = dflag + OT_WORD;
5438
        modrm = ldub_code(s->pc++);
5439
        mod = (modrm >> 6) & 3;
5440
        rm = (modrm & 7) | REX_B(s);
5441
        reg = ((modrm >> 3) & 7) | rex_r;
5442
        if (mod != 3) {
5443
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5444
            opreg = OR_TMP0;
5445
        } else {
5446
            opreg = rm;
5447
        }
5448
        gen_op_mov_TN_reg(ot, 1, reg);
5449

    
5450
        if (shift) {
5451
            val = ldub_code(s->pc++);
5452
            tcg_gen_movi_tl(cpu_T3, val);
5453
        } else {
5454
            tcg_gen_mov_tl(cpu_T3, cpu_regs[R_ECX]);
5455
        }
5456
        gen_shiftd_rm_T1_T3(s, ot, opreg, op);
5457
        break;
5458

    
5459
        /************************/
5460
        /* floats */
5461
    case 0xd8 ... 0xdf:
5462
        if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
5463
            /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5464
            /* XXX: what to do if illegal op ? */
5465
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5466
            break;
5467
        }
5468
        modrm = ldub_code(s->pc++);
5469
        mod = (modrm >> 6) & 3;
5470
        rm = modrm & 7;
5471
        op = ((b & 7) << 3) | ((modrm >> 3) & 7);
5472
        if (mod != 3) {
5473
            /* memory op */
5474
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5475
            switch(op) {
5476
            case 0x00 ... 0x07: /* fxxxs */
5477
            case 0x10 ... 0x17: /* fixxxl */
5478
            case 0x20 ... 0x27: /* fxxxl */
5479
            case 0x30 ... 0x37: /* fixxx */
5480
                {
5481
                    int op1;
5482
                    op1 = op & 7;
5483

    
5484
                    switch(op >> 4) {
5485
                    case 0:
5486
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5487
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5488
                        gen_helper_flds_FT0(cpu_tmp2_i32);
5489
                        break;
5490
                    case 1:
5491
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5492
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5493
                        gen_helper_fildl_FT0(cpu_tmp2_i32);
5494
                        break;
5495
                    case 2:
5496
                        tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
5497
                                          (s->mem_index >> 2) - 1);
5498
                        gen_helper_fldl_FT0(cpu_tmp1_i64);
5499
                        break;
5500
                    case 3:
5501
                    default:
5502
                        gen_op_lds_T0_A0(OT_WORD + s->mem_index);
5503
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5504
                        gen_helper_fildl_FT0(cpu_tmp2_i32);
5505
                        break;
5506
                    }
5507

    
5508
                    gen_helper_fp_arith_ST0_FT0(op1);
5509
                    if (op1 == 3) {
5510
                        /* fcomp needs pop */
5511
                        gen_helper_fpop();
5512
                    }
5513
                }
5514
                break;
5515
            case 0x08: /* flds */
5516
            case 0x0a: /* fsts */
5517
            case 0x0b: /* fstps */
5518
            case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5519
            case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5520
            case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5521
                switch(op & 7) {
5522
                case 0:
5523
                    switch(op >> 4) {
5524
                    case 0:
5525
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5526
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5527
                        gen_helper_flds_ST0(cpu_tmp2_i32);
5528
                        break;
5529
                    case 1:
5530
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5531
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5532
                        gen_helper_fildl_ST0(cpu_tmp2_i32);
5533
                        break;
5534
                    case 2:
5535
                        tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
5536
                                          (s->mem_index >> 2) - 1);
5537
                        gen_helper_fldl_ST0(cpu_tmp1_i64);
5538
                        break;
5539
                    case 3:
5540
                    default:
5541
                        gen_op_lds_T0_A0(OT_WORD + s->mem_index);
5542
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5543
                        gen_helper_fildl_ST0(cpu_tmp2_i32);
5544
                        break;
5545
                    }
5546
                    break;
5547
                case 1:
5548
                    /* XXX: the corresponding CPUID bit must be tested ! */
5549
                    switch(op >> 4) {
5550
                    case 1:
5551
                        gen_helper_fisttl_ST0(cpu_tmp2_i32);
5552
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5553
                        gen_op_st_T0_A0(OT_LONG + s->mem_index);
5554
                        break;
5555
                    case 2:
5556
                        gen_helper_fisttll_ST0(cpu_tmp1_i64);
5557
                        tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
5558
                                          (s->mem_index >> 2) - 1);
5559
                        break;
5560
                    case 3:
5561
                    default:
5562
                        gen_helper_fistt_ST0(cpu_tmp2_i32);
5563
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5564
                        gen_op_st_T0_A0(OT_WORD + s->mem_index);
5565
                        break;
5566
                    }
5567
                    gen_helper_fpop();
5568
                    break;
5569
                default:
5570
                    switch(op >> 4) {
5571
                    case 0:
5572
                        gen_helper_fsts_ST0(cpu_tmp2_i32);
5573
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5574
                        gen_op_st_T0_A0(OT_LONG + s->mem_index);
5575
                        break;
5576
                    case 1:
5577
                        gen_helper_fistl_ST0(cpu_tmp2_i32);
5578
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5579
                        gen_op_st_T0_A0(OT_LONG + s->mem_index);
5580
                        break;
5581
                    case 2:
5582
                        gen_helper_fstl_ST0(cpu_tmp1_i64);
5583
                        tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
5584
                                          (s->mem_index >> 2) - 1);
5585
                        break;
5586
                    case 3:
5587
                    default:
5588
                        gen_helper_fist_ST0(cpu_tmp2_i32);
5589
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5590
                        gen_op_st_T0_A0(OT_WORD + s->mem_index);
5591
                        break;
5592
                    }
5593
                    if ((op & 7) == 3)
5594
                        gen_helper_fpop();
5595
                    break;
5596
                }
5597
                break;
5598
            case 0x0c: /* fldenv mem */
5599
                if (s->cc_op != CC_OP_DYNAMIC)
5600
                    gen_op_set_cc_op(s->cc_op);
5601
                gen_jmp_im(pc_start - s->cs_base);
5602
                gen_helper_fldenv(
5603
                                   cpu_A0, tcg_const_i32(s->dflag));
5604
                break;
5605
            case 0x0d: /* fldcw mem */
5606
                gen_op_ld_T0_A0(OT_WORD + s->mem_index);
5607
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5608
                gen_helper_fldcw(cpu_tmp2_i32);
5609
                break;
5610
            case 0x0e: /* fnstenv mem */
5611
                if (s->cc_op != CC_OP_DYNAMIC)
5612
                    gen_op_set_cc_op(s->cc_op);
5613
                gen_jmp_im(pc_start - s->cs_base);
5614
                gen_helper_fstenv(cpu_A0, tcg_const_i32(s->dflag));
5615
                break;
5616
            case 0x0f: /* fnstcw mem */
5617
                gen_helper_fnstcw(cpu_tmp2_i32);
5618
                tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5619
                gen_op_st_T0_A0(OT_WORD + s->mem_index);
5620
                break;
5621
            case 0x1d: /* fldt mem */
5622
                if (s->cc_op != CC_OP_DYNAMIC)
5623
                    gen_op_set_cc_op(s->cc_op);
5624
                gen_jmp_im(pc_start - s->cs_base);
5625
                gen_helper_fldt_ST0(cpu_A0);
5626
                break;
5627
            case 0x1f: /* fstpt mem */
5628
                if (s->cc_op != CC_OP_DYNAMIC)
5629
                    gen_op_set_cc_op(s->cc_op);
5630
                gen_jmp_im(pc_start - s->cs_base);
5631
                gen_helper_fstt_ST0(cpu_A0);
5632
                gen_helper_fpop();
5633
                break;
5634
            case 0x2c: /* frstor mem */
5635
                if (s->cc_op != CC_OP_DYNAMIC)
5636
                    gen_op_set_cc_op(s->cc_op);
5637
                gen_jmp_im(pc_start - s->cs_base);
5638
                gen_helper_frstor(cpu_A0, tcg_const_i32(s->dflag));
5639
                break;
5640
            case 0x2e: /* fnsave mem */
5641
                if (s->cc_op != CC_OP_DYNAMIC)
5642
                    gen_op_set_cc_op(s->cc_op);
5643
                gen_jmp_im(pc_start - s->cs_base);
5644
                gen_helper_fsave(cpu_A0, tcg_const_i32(s->dflag));
5645
                break;
5646
            case 0x2f: /* fnstsw mem */
5647
                gen_helper_fnstsw(cpu_tmp2_i32);
5648
                tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5649
                gen_op_st_T0_A0(OT_WORD + s->mem_index);
5650
                break;
5651
            case 0x3c: /* fbld */
5652
                if (s->cc_op != CC_OP_DYNAMIC)
5653
                    gen_op_set_cc_op(s->cc_op);
5654
                gen_jmp_im(pc_start - s->cs_base);
5655
                gen_helper_fbld_ST0(cpu_A0);
5656
                break;
5657
            case 0x3e: /* fbstp */
5658
                if (s->cc_op != CC_OP_DYNAMIC)
5659
                    gen_op_set_cc_op(s->cc_op);
5660
                gen_jmp_im(pc_start - s->cs_base);
5661
                gen_helper_fbst_ST0(cpu_A0);
5662
                gen_helper_fpop();
5663
                break;
5664
            case 0x3d: /* fildll */
5665
                tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
5666
                                  (s->mem_index >> 2) - 1);
5667
                gen_helper_fildll_ST0(cpu_tmp1_i64);
5668
                break;
5669
            case 0x3f: /* fistpll */
5670
                gen_helper_fistll_ST0(cpu_tmp1_i64);
5671
                tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
5672
                                  (s->mem_index >> 2) - 1);
5673
                gen_helper_fpop();
5674
                break;
5675
            default:
5676
                goto illegal_op;
5677
            }
5678
        } else {
5679
            /* register float ops */
5680
            opreg = rm;
5681

    
5682
            switch(op) {
5683
            case 0x08: /* fld sti */
5684
                gen_helper_fpush();
5685
                gen_helper_fmov_ST0_STN(tcg_const_i32((opreg + 1) & 7));
5686
                break;
5687
            case 0x09: /* fxchg sti */
5688
            case 0x29: /* fxchg4 sti, undocumented op */
5689
            case 0x39: /* fxchg7 sti, undocumented op */
5690
                gen_helper_fxchg_ST0_STN(tcg_const_i32(opreg));
5691
                break;
5692
            case 0x0a: /* grp d9/2 */
5693
                switch(rm) {
5694
                case 0: /* fnop */
5695
                    /* check exceptions (FreeBSD FPU probe) */
5696
                    if (s->cc_op != CC_OP_DYNAMIC)
5697
                        gen_op_set_cc_op(s->cc_op);
5698
                    gen_jmp_im(pc_start - s->cs_base);
5699
                    gen_helper_fwait();
5700
                    break;
5701
                default:
5702
                    goto illegal_op;
5703
                }
5704
                break;
5705
            case 0x0c: /* grp d9/4 */
5706
                switch(rm) {
5707
                case 0: /* fchs */
5708
                    gen_helper_fchs_ST0();
5709
                    break;
5710
                case 1: /* fabs */
5711
                    gen_helper_fabs_ST0();
5712
                    break;
5713
                case 4: /* ftst */
5714
                    gen_helper_fldz_FT0();
5715
                    gen_helper_fcom_ST0_FT0();
5716
                    break;
5717
                case 5: /* fxam */
5718
                    gen_helper_fxam_ST0();
5719
                    break;
5720
                default:
5721
                    goto illegal_op;
5722
                }
5723
                break;
5724
            case 0x0d: /* grp d9/5 */
5725
                {
5726
                    switch(rm) {
5727
                    case 0:
5728
                        gen_helper_fpush();
5729
                        gen_helper_fld1_ST0();
5730
                        break;
5731
                    case 1:
5732
                        gen_helper_fpush();
5733
                        gen_helper_fldl2t_ST0();
5734
                        break;
5735
                    case 2:
5736
                        gen_helper_fpush();
5737
                        gen_helper_fldl2e_ST0();
5738
                        break;
5739
                    case 3:
5740
                        gen_helper_fpush();
5741
                        gen_helper_fldpi_ST0();
5742
                        break;
5743
                    case 4:
5744
                        gen_helper_fpush();
5745
                        gen_helper_fldlg2_ST0();
5746
                        break;
5747
                    case 5:
5748
                        gen_helper_fpush();
5749
                        gen_helper_fldln2_ST0();
5750
                        break;
5751
                    case 6:
5752
                        gen_helper_fpush();
5753
                        gen_helper_fldz_ST0();
5754
                        break;
5755
                    default:
5756
                        goto illegal_op;
5757
                    }
5758
                }
5759
                break;
5760
            case 0x0e: /* grp d9/6 */
5761
                switch(rm) {
5762
                case 0: /* f2xm1 */
5763
                    gen_helper_f2xm1();
5764
                    break;
5765
                case 1: /* fyl2x */
5766
                    gen_helper_fyl2x();
5767
                    break;
5768
                case 2: /* fptan */
5769
                    gen_helper_fptan();
5770
                    break;
5771
                case 3: /* fpatan */
5772
                    gen_helper_fpatan();
5773
                    break;
5774
                case 4: /* fxtract */
5775
                    gen_helper_fxtract();
5776
                    break;
5777
                case 5: /* fprem1 */
5778
                    gen_helper_fprem1();
5779
                    break;
5780
                case 6: /* fdecstp */
5781
                    gen_helper_fdecstp();
5782
                    break;
5783
                default:
5784
                case 7: /* fincstp */
5785
                    gen_helper_fincstp();
5786
                    break;
5787
                }
5788
                break;
5789
            case 0x0f: /* grp d9/7 */
5790
                switch(rm) {
5791
                case 0: /* fprem */
5792
                    gen_helper_fprem();
5793
                    break;
5794
                case 1: /* fyl2xp1 */
5795
                    gen_helper_fyl2xp1();
5796
                    break;
5797
                case 2: /* fsqrt */
5798
                    gen_helper_fsqrt();
5799
                    break;
5800
                case 3: /* fsincos */
5801
                    gen_helper_fsincos();
5802
                    break;
5803
                case 5: /* fscale */
5804
                    gen_helper_fscale();
5805
                    break;
5806
                case 4: /* frndint */
5807
                    gen_helper_frndint();
5808
                    break;
5809
                case 6: /* fsin */
5810
                    gen_helper_fsin();
5811
                    break;
5812
                default:
5813
                case 7: /* fcos */
5814
                    gen_helper_fcos();
5815
                    break;
5816
                }
5817
                break;
5818
            case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
5819
            case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
5820
            case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
5821
                {
5822
                    int op1;
5823

    
5824
                    op1 = op & 7;
5825
                    if (op >= 0x20) {
5826
                        gen_helper_fp_arith_STN_ST0(op1, opreg);
5827
                        if (op >= 0x30)
5828
                            gen_helper_fpop();
5829
                    } else {
5830
                        gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5831
                        gen_helper_fp_arith_ST0_FT0(op1);
5832
                    }
5833
                }
5834
                break;
5835
            case 0x02: /* fcom */
5836
            case 0x22: /* fcom2, undocumented op */
5837
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5838
                gen_helper_fcom_ST0_FT0();
5839
                break;
5840
            case 0x03: /* fcomp */
5841
            case 0x23: /* fcomp3, undocumented op */
5842
            case 0x32: /* fcomp5, undocumented op */
5843
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5844
                gen_helper_fcom_ST0_FT0();
5845
                gen_helper_fpop();
5846
                break;
5847
            case 0x15: /* da/5 */
5848
                switch(rm) {
5849
                case 1: /* fucompp */
5850
                    gen_helper_fmov_FT0_STN(tcg_const_i32(1));
5851
                    gen_helper_fucom_ST0_FT0();
5852
                    gen_helper_fpop();
5853
                    gen_helper_fpop();
5854
                    break;
5855
                default:
5856
                    goto illegal_op;
5857
                }
5858
                break;
5859
            case 0x1c:
5860
                switch(rm) {
5861
                case 0: /* feni (287 only, just do nop here) */
5862
                    break;
5863
                case 1: /* fdisi (287 only, just do nop here) */
5864
                    break;
5865
                case 2: /* fclex */
5866
                    gen_helper_fclex();
5867
                    break;
5868
                case 3: /* fninit */
5869
                    gen_helper_fninit();
5870
                    break;
5871
                case 4: /* fsetpm (287 only, just do nop here) */
5872
                    break;
5873
                default:
5874
                    goto illegal_op;
5875
                }
5876
                break;
5877
            case 0x1d: /* fucomi */
5878
                if (s->cc_op != CC_OP_DYNAMIC)
5879
                    gen_op_set_cc_op(s->cc_op);
5880
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5881
                gen_helper_fucomi_ST0_FT0();
5882
                s->cc_op = CC_OP_EFLAGS;
5883
                break;
5884
            case 0x1e: /* fcomi */
5885
                if (s->cc_op != CC_OP_DYNAMIC)
5886
                    gen_op_set_cc_op(s->cc_op);
5887
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5888
                gen_helper_fcomi_ST0_FT0();
5889
                s->cc_op = CC_OP_EFLAGS;
5890
                break;
5891
            case 0x28: /* ffree sti */
5892
                gen_helper_ffree_STN(tcg_const_i32(opreg));
5893
                break;
5894
            case 0x2a: /* fst sti */
5895
                gen_helper_fmov_STN_ST0(tcg_const_i32(opreg));
5896
                break;
5897
            case 0x2b: /* fstp sti */
5898
            case 0x0b: /* fstp1 sti, undocumented op */
5899
            case 0x3a: /* fstp8 sti, undocumented op */
5900
            case 0x3b: /* fstp9 sti, undocumented op */
5901
                gen_helper_fmov_STN_ST0(tcg_const_i32(opreg));
5902
                gen_helper_fpop();
5903
                break;
5904
            case 0x2c: /* fucom st(i) */
5905
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5906
                gen_helper_fucom_ST0_FT0();
5907
                break;
5908
            case 0x2d: /* fucomp st(i) */
5909
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5910
                gen_helper_fucom_ST0_FT0();
5911
                gen_helper_fpop();
5912
                break;
5913
            case 0x33: /* de/3 */
5914
                switch(rm) {
5915
                case 1: /* fcompp */
5916
                    gen_helper_fmov_FT0_STN(tcg_const_i32(1));
5917
                    gen_helper_fcom_ST0_FT0();
5918
                    gen_helper_fpop();
5919
                    gen_helper_fpop();
5920
                    break;
5921
                default:
5922
                    goto illegal_op;
5923
                }
5924
                break;
5925
            case 0x38: /* ffreep sti, undocumented op */
5926
                gen_helper_ffree_STN(tcg_const_i32(opreg));
5927
                gen_helper_fpop();
5928
                break;
5929
            case 0x3c: /* df/4 */
5930
                switch(rm) {
5931
                case 0:
5932
                    gen_helper_fnstsw(cpu_tmp2_i32);
5933
                    tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5934
                    gen_op_mov_reg_T0(OT_WORD, R_EAX);
5935
                    break;
5936
                default:
5937
                    goto illegal_op;
5938
                }
5939
                break;
5940
            case 0x3d: /* fucomip */
5941
                if (s->cc_op != CC_OP_DYNAMIC)
5942
                    gen_op_set_cc_op(s->cc_op);
5943
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5944
                gen_helper_fucomi_ST0_FT0();
5945
                gen_helper_fpop();
5946
                s->cc_op = CC_OP_EFLAGS;
5947
                break;
5948
            case 0x3e: /* fcomip */
5949
                if (s->cc_op != CC_OP_DYNAMIC)
5950
                    gen_op_set_cc_op(s->cc_op);
5951
                gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
5952
                gen_helper_fcomi_ST0_FT0();
5953
                gen_helper_fpop();
5954
                s->cc_op = CC_OP_EFLAGS;
5955
                break;
5956
            case 0x10 ... 0x13: /* fcmovxx */
5957
            case 0x18 ... 0x1b:
5958
                {
5959
                    int op1, l1;
5960
                    static const uint8_t fcmov_cc[8] = {
5961
                        (JCC_B << 1),
5962
                        (JCC_Z << 1),
5963
                        (JCC_BE << 1),
5964
                        (JCC_P << 1),
5965
                    };
5966
                    op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
5967
                    l1 = gen_new_label();
5968
                    gen_jcc1(s, s->cc_op, op1, l1);
5969
                    gen_helper_fmov_ST0_STN(tcg_const_i32(opreg));
5970
                    gen_set_label(l1);
5971
                }
5972
                break;
5973
            default:
5974
                goto illegal_op;
5975
            }
5976
        }
5977
        break;
5978
        /************************/
5979
        /* string ops */
5980

    
5981
    case 0xa4: /* movsS */
5982
    case 0xa5:
5983
        if ((b & 1) == 0)
5984
            ot = OT_BYTE;
5985
        else
5986
            ot = dflag + OT_WORD;
5987

    
5988
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5989
            gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5990
        } else {
5991
            gen_movs(s, ot);
5992
        }
5993
        break;
5994

    
5995
    case 0xaa: /* stosS */
5996
    case 0xab:
5997
        if ((b & 1) == 0)
5998
            ot = OT_BYTE;
5999
        else
6000
            ot = dflag + OT_WORD;
6001

    
6002
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6003
            gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6004
        } else {
6005
            gen_stos(s, ot);
6006
        }
6007
        break;
6008
    case 0xac: /* lodsS */
6009
    case 0xad:
6010
        if ((b & 1) == 0)
6011
            ot = OT_BYTE;
6012
        else
6013
            ot = dflag + OT_WORD;
6014
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6015
            gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6016
        } else {
6017
            gen_lods(s, ot);
6018
        }
6019
        break;
6020
    case 0xae: /* scasS */
6021
    case 0xaf:
6022
        if ((b & 1) == 0)
6023
            ot = OT_BYTE;
6024
        else
6025
            ot = dflag + OT_WORD;
6026
        if (prefixes & PREFIX_REPNZ) {
6027
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6028
        } else if (prefixes & PREFIX_REPZ) {
6029
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6030
        } else {
6031
            gen_scas(s, ot);
6032
            s->cc_op = CC_OP_SUBB + ot;
6033
        }
6034
        break;
6035

    
6036
    case 0xa6: /* cmpsS */
6037
    case 0xa7:
6038
        if ((b & 1) == 0)
6039
            ot = OT_BYTE;
6040
        else
6041
            ot = dflag + OT_WORD;
6042
        if (prefixes & PREFIX_REPNZ) {
6043
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6044
        } else if (prefixes & PREFIX_REPZ) {
6045
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6046
        } else {
6047
            gen_cmps(s, ot);
6048
            s->cc_op = CC_OP_SUBB + ot;
6049
        }
6050
        break;
6051
    case 0x6c: /* insS */
6052
    case 0x6d:
6053
        if ((b & 1) == 0)
6054
            ot = OT_BYTE;
6055
        else
6056
            ot = dflag ? OT_LONG : OT_WORD;
6057
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6058
        gen_op_andl_T0_ffff();
6059
        gen_check_io(s, ot, pc_start - s->cs_base, 
6060
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
6061
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6062
            gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6063
        } else {
6064
            gen_ins(s, ot);
6065
            if (use_icount) {
6066
                gen_jmp(s, s->pc - s->cs_base);
6067
            }
6068
        }
6069
        break;
6070
    case 0x6e: /* outsS */
6071
    case 0x6f:
6072
        if ((b & 1) == 0)
6073
            ot = OT_BYTE;
6074
        else
6075
            ot = dflag ? OT_LONG : OT_WORD;
6076
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6077
        gen_op_andl_T0_ffff();
6078
        gen_check_io(s, ot, pc_start - s->cs_base,
6079
                     svm_is_rep(prefixes) | 4);
6080
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6081
            gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6082
        } else {
6083
            gen_outs(s, ot);
6084
            if (use_icount) {
6085
                gen_jmp(s, s->pc - s->cs_base);
6086
            }
6087
        }
6088
        break;
6089

    
6090
        /************************/
6091
        /* port I/O */
6092

    
6093
    case 0xe4:
6094
    case 0xe5:
6095
        if ((b & 1) == 0)
6096
            ot = OT_BYTE;
6097
        else
6098
            ot = dflag ? OT_LONG : OT_WORD;
6099
        val = ldub_code(s->pc++);
6100
        gen_op_movl_T0_im(val);
6101
        gen_check_io(s, ot, pc_start - s->cs_base,
6102
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6103
        if (use_icount)
6104
            gen_io_start();
6105
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6106
        gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
6107
        gen_op_mov_reg_T1(ot, R_EAX);
6108
        if (use_icount) {
6109
            gen_io_end();
6110
            gen_jmp(s, s->pc - s->cs_base);
6111
        }
6112
        break;
6113
    case 0xe6:
6114
    case 0xe7:
6115
        if ((b & 1) == 0)
6116
            ot = OT_BYTE;
6117
        else
6118
            ot = dflag ? OT_LONG : OT_WORD;
6119
        val = ldub_code(s->pc++);
6120
        gen_op_movl_T0_im(val);
6121
        gen_check_io(s, ot, pc_start - s->cs_base,
6122
                     svm_is_rep(prefixes));
6123
        gen_op_mov_TN_reg(ot, 1, R_EAX);
6124

    
6125
        if (use_icount)
6126
            gen_io_start();
6127
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6128
        tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
6129
        tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
6130
        gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6131
        if (use_icount) {
6132
            gen_io_end();
6133
            gen_jmp(s, s->pc - s->cs_base);
6134
        }
6135
        break;
6136
    case 0xec:
6137
    case 0xed:
6138
        if ((b & 1) == 0)
6139
            ot = OT_BYTE;
6140
        else
6141
            ot = dflag ? OT_LONG : OT_WORD;
6142
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6143
        gen_op_andl_T0_ffff();
6144
        gen_check_io(s, ot, pc_start - s->cs_base,
6145
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6146
        if (use_icount)
6147
            gen_io_start();
6148
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6149
        gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
6150
        gen_op_mov_reg_T1(ot, R_EAX);
6151
        if (use_icount) {
6152
            gen_io_end();
6153
            gen_jmp(s, s->pc - s->cs_base);
6154
        }
6155
        break;
6156
    case 0xee:
6157
    case 0xef:
6158
        if ((b & 1) == 0)
6159
            ot = OT_BYTE;
6160
        else
6161
            ot = dflag ? OT_LONG : OT_WORD;
6162
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6163
        gen_op_andl_T0_ffff();
6164
        gen_check_io(s, ot, pc_start - s->cs_base,
6165
                     svm_is_rep(prefixes));
6166
        gen_op_mov_TN_reg(ot, 1, R_EAX);
6167

    
6168
        if (use_icount)
6169
            gen_io_start();
6170
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6171
        tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
6172
        tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
6173
        gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6174
        if (use_icount) {
6175
            gen_io_end();
6176
            gen_jmp(s, s->pc - s->cs_base);
6177
        }
6178
        break;
6179

    
6180
        /************************/
6181
        /* control */
6182
    case 0xc2: /* ret im */
6183
        val = ldsw_code(s->pc);
6184
        s->pc += 2;
6185
        gen_pop_T0(s);
6186
        if (CODE64(s) && s->dflag)
6187
            s->dflag = 2;
6188
        gen_stack_update(s, val + (2 << s->dflag));
6189
        if (s->dflag == 0)
6190
            gen_op_andl_T0_ffff();
6191
        gen_op_jmp_T0();
6192
        gen_eob(s);
6193
        break;
6194
    case 0xc3: /* ret */
6195
        gen_pop_T0(s);
6196
        gen_pop_update(s);
6197
        if (s->dflag == 0)
6198
            gen_op_andl_T0_ffff();
6199
        gen_op_jmp_T0();
6200
        gen_eob(s);
6201
        break;
6202
    case 0xca: /* lret im */
6203
        val = ldsw_code(s->pc);
6204
        s->pc += 2;
6205
    do_lret:
6206
        if (s->pe && !s->vm86) {
6207
            if (s->cc_op != CC_OP_DYNAMIC)
6208
                gen_op_set_cc_op(s->cc_op);
6209
            gen_jmp_im(pc_start - s->cs_base);
6210
            gen_helper_lret_protected(tcg_const_i32(s->dflag),
6211
                                      tcg_const_i32(val));
6212
        } else {
6213
            gen_stack_A0(s);
6214
            /* pop offset */
6215
            gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
6216
            if (s->dflag == 0)
6217
                gen_op_andl_T0_ffff();
6218
            /* NOTE: keeping EIP updated is not a problem in case of
6219
               exception */
6220
            gen_op_jmp_T0();
6221
            /* pop selector */
6222
            gen_op_addl_A0_im(2 << s->dflag);
6223
            gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
6224
            gen_op_movl_seg_T0_vm(R_CS);
6225
            /* add stack offset */
6226
            gen_stack_update(s, val + (4 << s->dflag));
6227
        }
6228
        gen_eob(s);
6229
        break;
6230
    case 0xcb: /* lret */
6231
        val = 0;
6232
        goto do_lret;
6233
    case 0xcf: /* iret */
6234
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
6235
        if (!s->pe) {
6236
            /* real mode */
6237
            gen_helper_iret_real(tcg_const_i32(s->dflag));
6238
            s->cc_op = CC_OP_EFLAGS;
6239
        } else if (s->vm86) {
6240
            if (s->iopl != 3) {
6241
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6242
            } else {
6243
                gen_helper_iret_real(tcg_const_i32(s->dflag));
6244
                s->cc_op = CC_OP_EFLAGS;
6245
            }
6246
        } else {
6247
            if (s->cc_op != CC_OP_DYNAMIC)
6248
                gen_op_set_cc_op(s->cc_op);
6249
            gen_jmp_im(pc_start - s->cs_base);
6250
            gen_helper_iret_protected(tcg_const_i32(s->dflag), 
6251
                                      tcg_const_i32(s->pc - s->cs_base));
6252
            s->cc_op = CC_OP_EFLAGS;
6253
        }
6254
        gen_eob(s);
6255
        break;
6256
    case 0xe8: /* call im */
6257
        {
6258
            if (dflag)
6259
                tval = (int32_t)insn_get(s, OT_LONG);
6260
            else
6261
                tval = (int16_t)insn_get(s, OT_WORD);
6262
            next_eip = s->pc - s->cs_base;
6263
            tval += next_eip;
6264
            if (s->dflag == 0)
6265
                tval &= 0xffff;
6266
            else if(!CODE64(s))
6267
                tval &= 0xffffffff;
6268
            gen_movtl_T0_im(next_eip);
6269
            gen_push_T0(s);
6270
            gen_jmp(s, tval);
6271
        }
6272
        break;
6273
    case 0x9a: /* lcall im */
6274
        {
6275
            unsigned int selector, offset;
6276

    
6277
            if (CODE64(s))
6278
                goto illegal_op;
6279
            ot = dflag ? OT_LONG : OT_WORD;
6280
            offset = insn_get(s, ot);
6281
            selector = insn_get(s, OT_WORD);
6282

    
6283
            gen_op_movl_T0_im(selector);
6284
            gen_op_movl_T1_imu(offset);
6285
        }
6286
        goto do_lcall;
6287
    case 0xe9: /* jmp im */
6288
        if (dflag)
6289
            tval = (int32_t)insn_get(s, OT_LONG);
6290
        else
6291
            tval = (int16_t)insn_get(s, OT_WORD);
6292
        tval += s->pc - s->cs_base;
6293
        if (s->dflag == 0)
6294
            tval &= 0xffff;
6295
        else if(!CODE64(s))
6296
            tval &= 0xffffffff;
6297
        gen_jmp(s, tval);
6298
        break;
6299
    case 0xea: /* ljmp im */
6300
        {
6301
            unsigned int selector, offset;
6302

    
6303
            if (CODE64(s))
6304
                goto illegal_op;
6305
            ot = dflag ? OT_LONG : OT_WORD;
6306
            offset = insn_get(s, ot);
6307
            selector = insn_get(s, OT_WORD);
6308

    
6309
            gen_op_movl_T0_im(selector);
6310
            gen_op_movl_T1_imu(offset);
6311
        }
6312
        goto do_ljmp;
6313
    case 0xeb: /* jmp Jb */
6314
        tval = (int8_t)insn_get(s, OT_BYTE);
6315
        tval += s->pc - s->cs_base;
6316
        if (s->dflag == 0)
6317
            tval &= 0xffff;
6318
        gen_jmp(s, tval);
6319
        break;
6320
    case 0x70 ... 0x7f: /* jcc Jb */
6321
        tval = (int8_t)insn_get(s, OT_BYTE);
6322
        goto do_jcc;
6323
    case 0x180 ... 0x18f: /* jcc Jv */
6324
        if (dflag) {
6325
            tval = (int32_t)insn_get(s, OT_LONG);
6326
        } else {
6327
            tval = (int16_t)insn_get(s, OT_WORD);
6328
        }
6329
    do_jcc:
6330
        next_eip = s->pc - s->cs_base;
6331
        tval += next_eip;
6332
        if (s->dflag == 0)
6333
            tval &= 0xffff;
6334
        gen_jcc(s, b, tval, next_eip);
6335
        break;
6336

    
6337
    case 0x190 ... 0x19f: /* setcc Gv */
6338
        modrm = ldub_code(s->pc++);
6339
        gen_setcc(s, b);
6340
        gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
6341
        break;
6342
    case 0x140 ... 0x14f: /* cmov Gv, Ev */
6343
        {
6344
            int l1;
6345
            TCGv t0;
6346

    
6347
            ot = dflag + OT_WORD;
6348
            modrm = ldub_code(s->pc++);
6349
            reg = ((modrm >> 3) & 7) | rex_r;
6350
            mod = (modrm >> 6) & 3;
6351
            t0 = tcg_temp_local_new();
6352
            if (mod != 3) {
6353
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6354
                gen_op_ld_v(ot + s->mem_index, t0, cpu_A0);
6355
            } else {
6356
                rm = (modrm & 7) | REX_B(s);
6357
                gen_op_mov_v_reg(ot, t0, rm);
6358
            }
6359
#ifdef TARGET_X86_64
6360
            if (ot == OT_LONG) {
6361
                /* XXX: specific Intel behaviour ? */
6362
                l1 = gen_new_label();
6363
                gen_jcc1(s, s->cc_op, b ^ 1, l1);
6364
                tcg_gen_mov_tl(cpu_regs[reg], t0);
6365
                gen_set_label(l1);
6366
                tcg_gen_ext32u_tl(cpu_regs[reg], cpu_regs[reg]);
6367
            } else
6368
#endif
6369
            {
6370
                l1 = gen_new_label();
6371
                gen_jcc1(s, s->cc_op, b ^ 1, l1);
6372
                gen_op_mov_reg_v(ot, reg, t0);
6373
                gen_set_label(l1);
6374
            }
6375
            tcg_temp_free(t0);
6376
        }
6377
        break;
6378

    
6379
        /************************/
6380
        /* flags */
6381
    case 0x9c: /* pushf */
6382
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
6383
        if (s->vm86 && s->iopl != 3) {
6384
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6385
        } else {
6386
            if (s->cc_op != CC_OP_DYNAMIC)
6387
                gen_op_set_cc_op(s->cc_op);
6388
            gen_helper_read_eflags(cpu_T[0]);
6389
            gen_push_T0(s);
6390
        }
6391
        break;
6392
    case 0x9d: /* popf */
6393
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
6394
        if (s->vm86 && s->iopl != 3) {
6395
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6396
        } else {
6397
            gen_pop_T0(s);
6398
            if (s->cpl == 0) {
6399
                if (s->dflag) {
6400
                    gen_helper_write_eflags(cpu_T[0],
6401
                                       tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK)));
6402
                } else {
6403
                    gen_helper_write_eflags(cpu_T[0],
6404
                                       tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff));
6405
                }
6406
            } else {
6407
                if (s->cpl <= s->iopl) {
6408
                    if (s->dflag) {
6409
                        gen_helper_write_eflags(cpu_T[0],
6410
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK)));
6411
                    } else {
6412
                        gen_helper_write_eflags(cpu_T[0],
6413
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff));
6414
                    }
6415
                } else {
6416
                    if (s->dflag) {
6417
                        gen_helper_write_eflags(cpu_T[0],
6418
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK)));
6419
                    } else {
6420
                        gen_helper_write_eflags(cpu_T[0],
6421
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff));
6422
                    }
6423
                }
6424
            }
6425
            gen_pop_update(s);
6426
            s->cc_op = CC_OP_EFLAGS;
6427
            /* abort translation because TF flag may change */
6428
            gen_jmp_im(s->pc - s->cs_base);
6429
            gen_eob(s);
6430
        }
6431
        break;
6432
    case 0x9e: /* sahf */
6433
        if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6434
            goto illegal_op;
6435
        gen_op_mov_TN_reg(OT_BYTE, 0, R_AH);
6436
        if (s->cc_op != CC_OP_DYNAMIC)
6437
            gen_op_set_cc_op(s->cc_op);
6438
        gen_compute_eflags(cpu_cc_src);
6439
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
6440
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], CC_S | CC_Z | CC_A | CC_P | CC_C);
6441
        tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T[0]);
6442
        s->cc_op = CC_OP_EFLAGS;
6443
        break;
6444
    case 0x9f: /* lahf */
6445
        if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6446
            goto illegal_op;
6447
        if (s->cc_op != CC_OP_DYNAMIC)
6448
            gen_op_set_cc_op(s->cc_op);
6449
        gen_compute_eflags(cpu_T[0]);
6450
        /* Note: gen_compute_eflags() only gives the condition codes */
6451
        tcg_gen_ori_tl(cpu_T[0], cpu_T[0], 0x02);
6452
        gen_op_mov_reg_T0(OT_BYTE, R_AH);
6453
        break;
6454
    case 0xf5: /* cmc */
6455
        if (s->cc_op != CC_OP_DYNAMIC)
6456
            gen_op_set_cc_op(s->cc_op);
6457
        gen_compute_eflags(cpu_cc_src);
6458
        tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6459
        s->cc_op = CC_OP_EFLAGS;
6460
        break;
6461
    case 0xf8: /* clc */
6462
        if (s->cc_op != CC_OP_DYNAMIC)
6463
            gen_op_set_cc_op(s->cc_op);
6464
        gen_compute_eflags(cpu_cc_src);
6465
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
6466
        s->cc_op = CC_OP_EFLAGS;
6467
        break;
6468
    case 0xf9: /* stc */
6469
        if (s->cc_op != CC_OP_DYNAMIC)
6470
            gen_op_set_cc_op(s->cc_op);
6471
        gen_compute_eflags(cpu_cc_src);
6472
        tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6473
        s->cc_op = CC_OP_EFLAGS;
6474
        break;
6475
    case 0xfc: /* cld */
6476
        tcg_gen_movi_i32(cpu_tmp2_i32, 1);
6477
        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUState, df));
6478
        break;
6479
    case 0xfd: /* std */
6480
        tcg_gen_movi_i32(cpu_tmp2_i32, -1);
6481
        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUState, df));
6482
        break;
6483

    
6484
        /************************/
6485
        /* bit operations */
6486
    case 0x1ba: /* bt/bts/btr/btc Gv, im */
6487
        ot = dflag + OT_WORD;
6488
        modrm = ldub_code(s->pc++);
6489
        op = (modrm >> 3) & 7;
6490
        mod = (modrm >> 6) & 3;
6491
        rm = (modrm & 7) | REX_B(s);
6492
        if (mod != 3) {
6493
            s->rip_offset = 1;
6494
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6495
            gen_op_ld_T0_A0(ot + s->mem_index);
6496
        } else {
6497
            gen_op_mov_TN_reg(ot, 0, rm);
6498
        }
6499
        /* load shift */
6500
        val = ldub_code(s->pc++);
6501
        gen_op_movl_T1_im(val);
6502
        if (op < 4)
6503
            goto illegal_op;
6504
        op -= 4;
6505
        goto bt_op;
6506
    case 0x1a3: /* bt Gv, Ev */
6507
        op = 0;
6508
        goto do_btx;
6509
    case 0x1ab: /* bts */
6510
        op = 1;
6511
        goto do_btx;
6512
    case 0x1b3: /* btr */
6513
        op = 2;
6514
        goto do_btx;
6515
    case 0x1bb: /* btc */
6516
        op = 3;
6517
    do_btx:
6518
        ot = dflag + OT_WORD;
6519
        modrm = ldub_code(s->pc++);
6520
        reg = ((modrm >> 3) & 7) | rex_r;
6521
        mod = (modrm >> 6) & 3;
6522
        rm = (modrm & 7) | REX_B(s);
6523
        gen_op_mov_TN_reg(OT_LONG, 1, reg);
6524
        if (mod != 3) {
6525
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6526
            /* specific case: we need to add a displacement */
6527
            gen_exts(ot, cpu_T[1]);
6528
            tcg_gen_sari_tl(cpu_tmp0, cpu_T[1], 3 + ot);
6529
            tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
6530
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
6531
            gen_op_ld_T0_A0(ot + s->mem_index);
6532
        } else {
6533
            gen_op_mov_TN_reg(ot, 0, rm);
6534
        }
6535
    bt_op:
6536
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], (1 << (3 + ot)) - 1);
6537
        switch(op) {
6538
        case 0:
6539
            tcg_gen_shr_tl(cpu_cc_src, cpu_T[0], cpu_T[1]);
6540
            tcg_gen_movi_tl(cpu_cc_dst, 0);
6541
            break;
6542
        case 1:
6543
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6544
            tcg_gen_movi_tl(cpu_tmp0, 1);
6545
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6546
            tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6547
            break;
6548
        case 2:
6549
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6550
            tcg_gen_movi_tl(cpu_tmp0, 1);
6551
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6552
            tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
6553
            tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6554
            break;
6555
        default:
6556
        case 3:
6557
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6558
            tcg_gen_movi_tl(cpu_tmp0, 1);
6559
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6560
            tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6561
            break;
6562
        }
6563
        s->cc_op = CC_OP_SARB + ot;
6564
        if (op != 0) {
6565
            if (mod != 3)
6566
                gen_op_st_T0_A0(ot + s->mem_index);
6567
            else
6568
                gen_op_mov_reg_T0(ot, rm);
6569
            tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
6570
            tcg_gen_movi_tl(cpu_cc_dst, 0);
6571
        }
6572
        break;
6573
    case 0x1bc: /* bsf */
6574
    case 0x1bd: /* bsr */
6575
        {
6576
            int label1;
6577
            TCGv t0;
6578

    
6579
            ot = dflag + OT_WORD;
6580
            modrm = ldub_code(s->pc++);
6581
            reg = ((modrm >> 3) & 7) | rex_r;
6582
            gen_ldst_modrm(s,modrm, ot, OR_TMP0, 0);
6583
            gen_extu(ot, cpu_T[0]);
6584
            t0 = tcg_temp_local_new();
6585
            tcg_gen_mov_tl(t0, cpu_T[0]);
6586
            if ((b & 1) && (prefixes & PREFIX_REPZ) &&
6587
                (s->cpuid_ext3_features & CPUID_EXT3_ABM)) {
6588
                switch(ot) {
6589
                case OT_WORD: gen_helper_lzcnt(cpu_T[0], t0,
6590
                    tcg_const_i32(16)); break;
6591
                case OT_LONG: gen_helper_lzcnt(cpu_T[0], t0,
6592
                    tcg_const_i32(32)); break;
6593
                case OT_QUAD: gen_helper_lzcnt(cpu_T[0], t0,
6594
                    tcg_const_i32(64)); break;
6595
                }
6596
                gen_op_mov_reg_T0(ot, reg);
6597
            } else {
6598
                label1 = gen_new_label();
6599
                tcg_gen_movi_tl(cpu_cc_dst, 0);
6600
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, label1);
6601
                if (b & 1) {
6602
                    gen_helper_bsr(cpu_T[0], t0);
6603
                } else {
6604
                    gen_helper_bsf(cpu_T[0], t0);
6605
                }
6606
                gen_op_mov_reg_T0(ot, reg);
6607
                tcg_gen_movi_tl(cpu_cc_dst, 1);
6608
                gen_set_label(label1);
6609
                tcg_gen_discard_tl(cpu_cc_src);
6610
                s->cc_op = CC_OP_LOGICB + ot;
6611
            }
6612
            tcg_temp_free(t0);
6613
        }
6614
        break;
6615
        /************************/
6616
        /* bcd */
6617
    case 0x27: /* daa */
6618
        if (CODE64(s))
6619
            goto illegal_op;
6620
        if (s->cc_op != CC_OP_DYNAMIC)
6621
            gen_op_set_cc_op(s->cc_op);
6622
        gen_helper_daa();
6623
        s->cc_op = CC_OP_EFLAGS;
6624
        break;
6625
    case 0x2f: /* das */
6626
        if (CODE64(s))
6627
            goto illegal_op;
6628
        if (s->cc_op != CC_OP_DYNAMIC)
6629
            gen_op_set_cc_op(s->cc_op);
6630
        gen_helper_das();
6631
        s->cc_op = CC_OP_EFLAGS;
6632
        break;
6633
    case 0x37: /* aaa */
6634
        if (CODE64(s))
6635
            goto illegal_op;
6636
        if (s->cc_op != CC_OP_DYNAMIC)
6637
            gen_op_set_cc_op(s->cc_op);
6638
        gen_helper_aaa();
6639
        s->cc_op = CC_OP_EFLAGS;
6640
        break;
6641
    case 0x3f: /* aas */
6642
        if (CODE64(s))
6643
            goto illegal_op;
6644
        if (s->cc_op != CC_OP_DYNAMIC)
6645
            gen_op_set_cc_op(s->cc_op);
6646
        gen_helper_aas();
6647
        s->cc_op = CC_OP_EFLAGS;
6648
        break;
6649
    case 0xd4: /* aam */
6650
        if (CODE64(s))
6651
            goto illegal_op;
6652
        val = ldub_code(s->pc++);
6653
        if (val == 0) {
6654
            gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
6655
        } else {
6656
            gen_helper_aam(tcg_const_i32(val));
6657
            s->cc_op = CC_OP_LOGICB;
6658
        }
6659
        break;
6660
    case 0xd5: /* aad */
6661
        if (CODE64(s))
6662
            goto illegal_op;
6663
        val = ldub_code(s->pc++);
6664
        gen_helper_aad(tcg_const_i32(val));
6665
        s->cc_op = CC_OP_LOGICB;
6666
        break;
6667
        /************************/
6668
        /* misc */
6669
    case 0x90: /* nop */
6670
        /* XXX: correct lock test for all insn */
6671
        if (prefixes & PREFIX_LOCK) {
6672
            goto illegal_op;
6673
        }
6674
        /* If REX_B is set, then this is xchg eax, r8d, not a nop.  */
6675
        if (REX_B(s)) {
6676
            goto do_xchg_reg_eax;
6677
        }
6678
        if (prefixes & PREFIX_REPZ) {
6679
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_PAUSE);
6680
        }
6681
        break;
6682
    case 0x9b: /* fwait */
6683
        if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
6684
            (HF_MP_MASK | HF_TS_MASK)) {
6685
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6686
        } else {
6687
            if (s->cc_op != CC_OP_DYNAMIC)
6688
                gen_op_set_cc_op(s->cc_op);
6689
            gen_jmp_im(pc_start - s->cs_base);
6690
            gen_helper_fwait();
6691
        }
6692
        break;
6693
    case 0xcc: /* int3 */
6694
        gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
6695
        break;
6696
    case 0xcd: /* int N */
6697
        val = ldub_code(s->pc++);
6698
        if (s->vm86 && s->iopl != 3) {
6699
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6700
        } else {
6701
            gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
6702
        }
6703
        break;
6704
    case 0xce: /* into */
6705
        if (CODE64(s))
6706
            goto illegal_op;
6707
        if (s->cc_op != CC_OP_DYNAMIC)
6708
            gen_op_set_cc_op(s->cc_op);
6709
        gen_jmp_im(pc_start - s->cs_base);
6710
        gen_helper_into(tcg_const_i32(s->pc - pc_start));
6711
        break;
6712
#ifdef WANT_ICEBP
6713
    case 0xf1: /* icebp (undocumented, exits to external debugger) */
6714
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
6715
#if 1
6716
        gen_debug(s, pc_start - s->cs_base);
6717
#else
6718
        /* start debug */
6719
        tb_flush(cpu_single_env);
6720
        cpu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
6721
#endif
6722
        break;
6723
#endif
6724
    case 0xfa: /* cli */
6725
        if (!s->vm86) {
6726
            if (s->cpl <= s->iopl) {
6727
                gen_helper_cli();
6728
            } else {
6729
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6730
            }
6731
        } else {
6732
            if (s->iopl == 3) {
6733
                gen_helper_cli();
6734
            } else {
6735
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6736
            }
6737
        }
6738
        break;
6739
    case 0xfb: /* sti */
6740
        if (!s->vm86) {
6741
            if (s->cpl <= s->iopl) {
6742
            gen_sti:
6743
                gen_helper_sti();
6744
                /* interruptions are enabled only the first insn after sti */
6745
                /* If several instructions disable interrupts, only the
6746
                   _first_ does it */
6747
                if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
6748
                    gen_helper_set_inhibit_irq();
6749
                /* give a chance to handle pending irqs */
6750
                gen_jmp_im(s->pc - s->cs_base);
6751
                gen_eob(s);
6752
            } else {
6753
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6754
            }
6755
        } else {
6756
            if (s->iopl == 3) {
6757
                goto gen_sti;
6758
            } else {
6759
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6760
            }
6761
        }
6762
        break;
6763
    case 0x62: /* bound */
6764
        if (CODE64(s))
6765
            goto illegal_op;
6766
        ot = dflag ? OT_LONG : OT_WORD;
6767
        modrm = ldub_code(s->pc++);
6768
        reg = (modrm >> 3) & 7;
6769
        mod = (modrm >> 6) & 3;
6770
        if (mod == 3)
6771
            goto illegal_op;
6772
        gen_op_mov_TN_reg(ot, 0, reg);
6773
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6774
        gen_jmp_im(pc_start - s->cs_base);
6775
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6776
        if (ot == OT_WORD)
6777
            gen_helper_boundw(cpu_A0, cpu_tmp2_i32);
6778
        else
6779
            gen_helper_boundl(cpu_A0, cpu_tmp2_i32);
6780
        break;
6781
    case 0x1c8 ... 0x1cf: /* bswap reg */
6782
        reg = (b & 7) | REX_B(s);
6783
#ifdef TARGET_X86_64
6784
        if (dflag == 2) {
6785
            gen_op_mov_TN_reg(OT_QUAD, 0, reg);
6786
            tcg_gen_bswap64_i64(cpu_T[0], cpu_T[0]);
6787
            gen_op_mov_reg_T0(OT_QUAD, reg);
6788
        } else
6789
#endif
6790
        {
6791
            gen_op_mov_TN_reg(OT_LONG, 0, reg);
6792
            tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
6793
            tcg_gen_bswap32_tl(cpu_T[0], cpu_T[0]);
6794
            gen_op_mov_reg_T0(OT_LONG, reg);
6795
        }
6796
        break;
6797
    case 0xd6: /* salc */
6798
        if (CODE64(s))
6799
            goto illegal_op;
6800
        if (s->cc_op != CC_OP_DYNAMIC)
6801
            gen_op_set_cc_op(s->cc_op);
6802
        gen_compute_eflags_c(cpu_T[0]);
6803
        tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
6804
        gen_op_mov_reg_T0(OT_BYTE, R_EAX);
6805
        break;
6806
    case 0xe0: /* loopnz */
6807
    case 0xe1: /* loopz */
6808
    case 0xe2: /* loop */
6809
    case 0xe3: /* jecxz */
6810
        {
6811
            int l1, l2, l3;
6812

    
6813
            tval = (int8_t)insn_get(s, OT_BYTE);
6814
            next_eip = s->pc - s->cs_base;
6815
            tval += next_eip;
6816
            if (s->dflag == 0)
6817
                tval &= 0xffff;
6818

    
6819
            l1 = gen_new_label();
6820
            l2 = gen_new_label();
6821
            l3 = gen_new_label();
6822
            b &= 3;
6823
            switch(b) {
6824
            case 0: /* loopnz */
6825
            case 1: /* loopz */
6826
                if (s->cc_op != CC_OP_DYNAMIC)
6827
                    gen_op_set_cc_op(s->cc_op);
6828
                gen_op_add_reg_im(s->aflag, R_ECX, -1);
6829
                gen_op_jz_ecx(s->aflag, l3);
6830
                gen_compute_eflags(cpu_tmp0);
6831
                tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_Z);
6832
                if (b == 0) {
6833
                    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
6834
                } else {
6835
                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, l1);
6836
                }
6837
                break;
6838
            case 2: /* loop */
6839
                gen_op_add_reg_im(s->aflag, R_ECX, -1);
6840
                gen_op_jnz_ecx(s->aflag, l1);
6841
                break;
6842
            default:
6843
            case 3: /* jcxz */
6844
                gen_op_jz_ecx(s->aflag, l1);
6845
                break;
6846
            }
6847

    
6848
            gen_set_label(l3);
6849
            gen_jmp_im(next_eip);
6850
            tcg_gen_br(l2);
6851

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

    
7292
            modrm = ldub_code(s->pc++);
7293
            reg = ((modrm >> 3) & 7) | rex_r;
7294
            mod = (modrm >> 6) & 3;
7295
            rm = (modrm & 7) | REX_B(s);
7296

    
7297
            if (mod == 3) {
7298
                gen_op_mov_TN_reg(OT_LONG, 0, rm);
7299
                /* sign extend */
7300
                if (d_ot == OT_QUAD)
7301
                    tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
7302
                gen_op_mov_reg_T0(d_ot, reg);
7303
            } else {
7304
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7305
                if (d_ot == OT_QUAD) {
7306
                    gen_op_lds_T0_A0(OT_LONG + s->mem_index);
7307
                } else {
7308
                    gen_op_ld_T0_A0(OT_LONG + s->mem_index);
7309
                }
7310
                gen_op_mov_reg_T0(d_ot, reg);
7311
            }
7312
        } else
7313
#endif
7314
        {
7315
            int label1;
7316
            TCGv t0, t1, t2, a0;
7317

    
7318
            if (!s->pe || s->vm86)
7319
                goto illegal_op;
7320
            t0 = tcg_temp_local_new();
7321
            t1 = tcg_temp_local_new();
7322
            t2 = tcg_temp_local_new();
7323
            ot = OT_WORD;
7324
            modrm = ldub_code(s->pc++);
7325
            reg = (modrm >> 3) & 7;
7326
            mod = (modrm >> 6) & 3;
7327
            rm = modrm & 7;
7328
            if (mod != 3) {
7329
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7330
                gen_op_ld_v(ot + s->mem_index, t0, cpu_A0);
7331
                a0 = tcg_temp_local_new();
7332
                tcg_gen_mov_tl(a0, cpu_A0);
7333
            } else {
7334
                gen_op_mov_v_reg(ot, t0, rm);
7335
                TCGV_UNUSED(a0);
7336
            }
7337
            gen_op_mov_v_reg(ot, t1, reg);
7338
            tcg_gen_andi_tl(cpu_tmp0, t0, 3);
7339
            tcg_gen_andi_tl(t1, t1, 3);
7340
            tcg_gen_movi_tl(t2, 0);
7341
            label1 = gen_new_label();
7342
            tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, t1, label1);
7343
            tcg_gen_andi_tl(t0, t0, ~3);
7344
            tcg_gen_or_tl(t0, t0, t1);
7345
            tcg_gen_movi_tl(t2, CC_Z);
7346
            gen_set_label(label1);
7347
            if (mod != 3) {
7348
                gen_op_st_v(ot + s->mem_index, t0, a0);
7349
                tcg_temp_free(a0);
7350
           } else {
7351
                gen_op_mov_reg_v(ot, rm, t0);
7352
            }
7353
            if (s->cc_op != CC_OP_DYNAMIC)
7354
                gen_op_set_cc_op(s->cc_op);
7355
            gen_compute_eflags(cpu_cc_src);
7356
            tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
7357
            tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
7358
            s->cc_op = CC_OP_EFLAGS;
7359
            tcg_temp_free(t0);
7360
            tcg_temp_free(t1);
7361
            tcg_temp_free(t2);
7362
        }
7363
        break;
7364
    case 0x102: /* lar */
7365
    case 0x103: /* lsl */
7366
        {
7367
            int label1;
7368
            TCGv t0;
7369
            if (!s->pe || s->vm86)
7370
                goto illegal_op;
7371
            ot = dflag ? OT_LONG : OT_WORD;
7372
            modrm = ldub_code(s->pc++);
7373
            reg = ((modrm >> 3) & 7) | rex_r;
7374
            gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
7375
            t0 = tcg_temp_local_new();
7376
            if (s->cc_op != CC_OP_DYNAMIC)
7377
                gen_op_set_cc_op(s->cc_op);
7378
            if (b == 0x102)
7379
                gen_helper_lar(t0, cpu_T[0]);
7380
            else
7381
                gen_helper_lsl(t0, cpu_T[0]);
7382
            tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
7383
            label1 = gen_new_label();
7384
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
7385
            gen_op_mov_reg_v(ot, reg, t0);
7386
            gen_set_label(label1);
7387
            s->cc_op = CC_OP_EFLAGS;
7388
            tcg_temp_free(t0);
7389
        }
7390
        break;
7391
    case 0x118:
7392
        modrm = ldub_code(s->pc++);
7393
        mod = (modrm >> 6) & 3;
7394
        op = (modrm >> 3) & 7;
7395
        switch(op) {
7396
        case 0: /* prefetchnta */
7397
        case 1: /* prefetchnt0 */
7398
        case 2: /* prefetchnt0 */
7399
        case 3: /* prefetchnt0 */
7400
            if (mod == 3)
7401
                goto illegal_op;
7402
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7403
            /* nothing more to do */
7404
            break;
7405
        default: /* nop (multi byte) */
7406
            gen_nop_modrm(s, modrm);
7407
            break;
7408
        }
7409
        break;
7410
    case 0x119 ... 0x11f: /* nop (multi byte) */
7411
        modrm = ldub_code(s->pc++);
7412
        gen_nop_modrm(s, modrm);
7413
        break;
7414
    case 0x120: /* mov reg, crN */
7415
    case 0x122: /* mov crN, reg */
7416
        if (s->cpl != 0) {
7417
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7418
        } else {
7419
            modrm = ldub_code(s->pc++);
7420
            if ((modrm & 0xc0) != 0xc0)
7421
                goto illegal_op;
7422
            rm = (modrm & 7) | REX_B(s);
7423
            reg = ((modrm >> 3) & 7) | rex_r;
7424
            if (CODE64(s))
7425
                ot = OT_QUAD;
7426
            else
7427
                ot = OT_LONG;
7428
            if ((prefixes & PREFIX_LOCK) && (reg == 0) &&
7429
                (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
7430
                reg = 8;
7431
            }
7432
            switch(reg) {
7433
            case 0:
7434
            case 2:
7435
            case 3:
7436
            case 4:
7437
            case 8:
7438
                if (s->cc_op != CC_OP_DYNAMIC)
7439
                    gen_op_set_cc_op(s->cc_op);
7440
                gen_jmp_im(pc_start - s->cs_base);
7441
                if (b & 2) {
7442
                    gen_op_mov_TN_reg(ot, 0, rm);
7443
                    gen_helper_write_crN(tcg_const_i32(reg), cpu_T[0]);
7444
                    gen_jmp_im(s->pc - s->cs_base);
7445
                    gen_eob(s);
7446
                } else {
7447
                    gen_helper_read_crN(cpu_T[0], tcg_const_i32(reg));
7448
                    gen_op_mov_reg_T0(ot, rm);
7449
                }
7450
                break;
7451
            default:
7452
                goto illegal_op;
7453
            }
7454
        }
7455
        break;
7456
    case 0x121: /* mov reg, drN */
7457
    case 0x123: /* mov drN, reg */
7458
        if (s->cpl != 0) {
7459
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7460
        } else {
7461
            modrm = ldub_code(s->pc++);
7462
            if ((modrm & 0xc0) != 0xc0)
7463
                goto illegal_op;
7464
            rm = (modrm & 7) | REX_B(s);
7465
            reg = ((modrm >> 3) & 7) | rex_r;
7466
            if (CODE64(s))
7467
                ot = OT_QUAD;
7468
            else
7469
                ot = OT_LONG;
7470
            /* XXX: do it dynamically with CR4.DE bit */
7471
            if (reg == 4 || reg == 5 || reg >= 8)
7472
                goto illegal_op;
7473
            if (b & 2) {
7474
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
7475
                gen_op_mov_TN_reg(ot, 0, rm);
7476
                gen_helper_movl_drN_T0(tcg_const_i32(reg), cpu_T[0]);
7477
                gen_jmp_im(s->pc - s->cs_base);
7478
                gen_eob(s);
7479
            } else {
7480
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
7481
                tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,dr[reg]));
7482
                gen_op_mov_reg_T0(ot, rm);
7483
            }
7484
        }
7485
        break;
7486
    case 0x106: /* clts */
7487
        if (s->cpl != 0) {
7488
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7489
        } else {
7490
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7491
            gen_helper_clts();
7492
            /* abort block because static cpu state changed */
7493
            gen_jmp_im(s->pc - s->cs_base);
7494
            gen_eob(s);
7495
        }
7496
        break;
7497
    /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7498
    case 0x1c3: /* MOVNTI reg, mem */
7499
        if (!(s->cpuid_features & CPUID_SSE2))
7500
            goto illegal_op;
7501
        ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
7502
        modrm = ldub_code(s->pc++);
7503
        mod = (modrm >> 6) & 3;
7504
        if (mod == 3)
7505
            goto illegal_op;
7506
        reg = ((modrm >> 3) & 7) | rex_r;
7507
        /* generate a generic store */
7508
        gen_ldst_modrm(s, modrm, ot, reg, 1);
7509
        break;
7510
    case 0x1ae:
7511
        modrm = ldub_code(s->pc++);
7512
        mod = (modrm >> 6) & 3;
7513
        op = (modrm >> 3) & 7;
7514
        switch(op) {
7515
        case 0: /* fxsave */
7516
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
7517
                (s->prefix & PREFIX_LOCK))
7518
                goto illegal_op;
7519
            if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
7520
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7521
                break;
7522
            }
7523
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7524
            if (s->cc_op != CC_OP_DYNAMIC)
7525
                gen_op_set_cc_op(s->cc_op);
7526
            gen_jmp_im(pc_start - s->cs_base);
7527
            gen_helper_fxsave(cpu_A0, tcg_const_i32((s->dflag == 2)));
7528
            break;
7529
        case 1: /* fxrstor */
7530
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
7531
                (s->prefix & PREFIX_LOCK))
7532
                goto illegal_op;
7533
            if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
7534
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7535
                break;
7536
            }
7537
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7538
            if (s->cc_op != CC_OP_DYNAMIC)
7539
                gen_op_set_cc_op(s->cc_op);
7540
            gen_jmp_im(pc_start - s->cs_base);
7541
            gen_helper_fxrstor(cpu_A0, tcg_const_i32((s->dflag == 2)));
7542
            break;
7543
        case 2: /* ldmxcsr */
7544
        case 3: /* stmxcsr */
7545
            if (s->flags & HF_TS_MASK) {
7546
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7547
                break;
7548
            }
7549
            if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
7550
                mod == 3)
7551
                goto illegal_op;
7552
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7553
            if (op == 2) {
7554
                gen_op_ld_T0_A0(OT_LONG + s->mem_index);
7555
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
7556
            } else {
7557
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
7558
                gen_op_st_T0_A0(OT_LONG + s->mem_index);
7559
            }
7560
            break;
7561
        case 5: /* lfence */
7562
        case 6: /* mfence */
7563
            if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE))
7564
                goto illegal_op;
7565
            break;
7566
        case 7: /* sfence / clflush */
7567
            if ((modrm & 0xc7) == 0xc0) {
7568
                /* sfence */
7569
                /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
7570
                if (!(s->cpuid_features & CPUID_SSE))
7571
                    goto illegal_op;
7572
            } else {
7573
                /* clflush */
7574
                if (!(s->cpuid_features & CPUID_CLFLUSH))
7575
                    goto illegal_op;
7576
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7577
            }
7578
            break;
7579
        default:
7580
            goto illegal_op;
7581
        }
7582
        break;
7583
    case 0x10d: /* 3DNow! prefetch(w) */
7584
        modrm = ldub_code(s->pc++);
7585
        mod = (modrm >> 6) & 3;
7586
        if (mod == 3)
7587
            goto illegal_op;
7588
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7589
        /* ignore for now */
7590
        break;
7591
    case 0x1aa: /* rsm */
7592
        gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
7593
        if (!(s->flags & HF_SMM_MASK))
7594
            goto illegal_op;
7595
        gen_update_cc_op(s);
7596
        gen_jmp_im(s->pc - s->cs_base);
7597
        gen_helper_rsm();
7598
        gen_eob(s);
7599
        break;
7600
    case 0x1b8: /* SSE4.2 popcnt */
7601
        if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
7602
             PREFIX_REPZ)
7603
            goto illegal_op;
7604
        if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
7605
            goto illegal_op;
7606

    
7607
        modrm = ldub_code(s->pc++);
7608
        reg = ((modrm >> 3) & 7);
7609

    
7610
        if (s->prefix & PREFIX_DATA)
7611
            ot = OT_WORD;
7612
        else if (s->dflag != 2)
7613
            ot = OT_LONG;
7614
        else
7615
            ot = OT_QUAD;
7616

    
7617
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
7618
        gen_helper_popcnt(cpu_T[0], cpu_T[0], tcg_const_i32(ot));
7619
        gen_op_mov_reg_T0(ot, reg);
7620

    
7621
        s->cc_op = CC_OP_EFLAGS;
7622
        break;
7623
    case 0x10e ... 0x10f:
7624
        /* 3DNow! instructions, ignore prefixes */
7625
        s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
7626
    case 0x110 ... 0x117:
7627
    case 0x128 ... 0x12f:
7628
    case 0x138 ... 0x13a:
7629
    case 0x150 ... 0x179:
7630
    case 0x17c ... 0x17f:
7631
    case 0x1c2:
7632
    case 0x1c4 ... 0x1c6:
7633
    case 0x1d0 ... 0x1fe:
7634
        gen_sse(s, b, pc_start, rex_r);
7635
        break;
7636
    default:
7637
        goto illegal_op;
7638
    }
7639
    /* lock generation */
7640
    if (s->prefix & PREFIX_LOCK)
7641
        gen_helper_unlock();
7642
    return s->pc;
7643
 illegal_op:
7644
    if (s->prefix & PREFIX_LOCK)
7645
        gen_helper_unlock();
7646
    /* XXX: ensure that no lock was generated */
7647
    gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
7648
    return s->pc;
7649
}
7650

    
7651
void optimize_flags_init(void)
7652
{
7653
#if TCG_TARGET_REG_BITS == 32
7654
    assert(sizeof(CCTable) == (1 << 3));
7655
#else
7656
    assert(sizeof(CCTable) == (1 << 4));
7657
#endif
7658
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
7659
    cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0,
7660
                                       offsetof(CPUState, cc_op), "cc_op");
7661
    cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_src),
7662
                                    "cc_src");
7663
    cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_dst),
7664
                                    "cc_dst");
7665
    cpu_cc_tmp = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_tmp),
7666
                                    "cc_tmp");
7667

    
7668
#ifdef TARGET_X86_64
7669
    cpu_regs[R_EAX] = tcg_global_mem_new_i64(TCG_AREG0,
7670
                                             offsetof(CPUState, regs[R_EAX]), "rax");
7671
    cpu_regs[R_ECX] = tcg_global_mem_new_i64(TCG_AREG0,
7672
                                             offsetof(CPUState, regs[R_ECX]), "rcx");
7673
    cpu_regs[R_EDX] = tcg_global_mem_new_i64(TCG_AREG0,
7674
                                             offsetof(CPUState, regs[R_EDX]), "rdx");
7675
    cpu_regs[R_EBX] = tcg_global_mem_new_i64(TCG_AREG0,
7676
                                             offsetof(CPUState, regs[R_EBX]), "rbx");
7677
    cpu_regs[R_ESP] = tcg_global_mem_new_i64(TCG_AREG0,
7678
                                             offsetof(CPUState, regs[R_ESP]), "rsp");
7679
    cpu_regs[R_EBP] = tcg_global_mem_new_i64(TCG_AREG0,
7680
                                             offsetof(CPUState, regs[R_EBP]), "rbp");
7681
    cpu_regs[R_ESI] = tcg_global_mem_new_i64(TCG_AREG0,
7682
                                             offsetof(CPUState, regs[R_ESI]), "rsi");
7683
    cpu_regs[R_EDI] = tcg_global_mem_new_i64(TCG_AREG0,
7684
                                             offsetof(CPUState, regs[R_EDI]), "rdi");
7685
    cpu_regs[8] = tcg_global_mem_new_i64(TCG_AREG0,
7686
                                         offsetof(CPUState, regs[8]), "r8");
7687
    cpu_regs[9] = tcg_global_mem_new_i64(TCG_AREG0,
7688
                                          offsetof(CPUState, regs[9]), "r9");
7689
    cpu_regs[10] = tcg_global_mem_new_i64(TCG_AREG0,
7690
                                          offsetof(CPUState, regs[10]), "r10");
7691
    cpu_regs[11] = tcg_global_mem_new_i64(TCG_AREG0,
7692
                                          offsetof(CPUState, regs[11]), "r11");
7693
    cpu_regs[12] = tcg_global_mem_new_i64(TCG_AREG0,
7694
                                          offsetof(CPUState, regs[12]), "r12");
7695
    cpu_regs[13] = tcg_global_mem_new_i64(TCG_AREG0,
7696
                                          offsetof(CPUState, regs[13]), "r13");
7697
    cpu_regs[14] = tcg_global_mem_new_i64(TCG_AREG0,
7698
                                          offsetof(CPUState, regs[14]), "r14");
7699
    cpu_regs[15] = tcg_global_mem_new_i64(TCG_AREG0,
7700
                                          offsetof(CPUState, regs[15]), "r15");
7701
#else
7702
    cpu_regs[R_EAX] = tcg_global_mem_new_i32(TCG_AREG0,
7703
                                             offsetof(CPUState, regs[R_EAX]), "eax");
7704
    cpu_regs[R_ECX] = tcg_global_mem_new_i32(TCG_AREG0,
7705
                                             offsetof(CPUState, regs[R_ECX]), "ecx");
7706
    cpu_regs[R_EDX] = tcg_global_mem_new_i32(TCG_AREG0,
7707
                                             offsetof(CPUState, regs[R_EDX]), "edx");
7708
    cpu_regs[R_EBX] = tcg_global_mem_new_i32(TCG_AREG0,
7709
                                             offsetof(CPUState, regs[R_EBX]), "ebx");
7710
    cpu_regs[R_ESP] = tcg_global_mem_new_i32(TCG_AREG0,
7711
                                             offsetof(CPUState, regs[R_ESP]), "esp");
7712
    cpu_regs[R_EBP] = tcg_global_mem_new_i32(TCG_AREG0,
7713
                                             offsetof(CPUState, regs[R_EBP]), "ebp");
7714
    cpu_regs[R_ESI] = tcg_global_mem_new_i32(TCG_AREG0,
7715
                                             offsetof(CPUState, regs[R_ESI]), "esi");
7716
    cpu_regs[R_EDI] = tcg_global_mem_new_i32(TCG_AREG0,
7717
                                             offsetof(CPUState, regs[R_EDI]), "edi");
7718
#endif
7719

    
7720
    /* register helpers */
7721
#define GEN_HELPER 2
7722
#include "helper.h"
7723
}
7724

    
7725
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
7726
   basic block 'tb'. If search_pc is TRUE, also generate PC
7727
   information for each intermediate instruction. */
7728
static inline void gen_intermediate_code_internal(CPUState *env,
7729
                                                  TranslationBlock *tb,
7730
                                                  int search_pc)
7731
{
7732
    DisasContext dc1, *dc = &dc1;
7733
    target_ulong pc_ptr;
7734
    uint16_t *gen_opc_end;
7735
    CPUBreakpoint *bp;
7736
    int j, lj;
7737
    uint64_t flags;
7738
    target_ulong pc_start;
7739
    target_ulong cs_base;
7740
    int num_insns;
7741
    int max_insns;
7742

    
7743
    /* generate intermediate code */
7744
    pc_start = tb->pc;
7745
    cs_base = tb->cs_base;
7746
    flags = tb->flags;
7747

    
7748
    dc->pe = (flags >> HF_PE_SHIFT) & 1;
7749
    dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
7750
    dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
7751
    dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
7752
    dc->f_st = 0;
7753
    dc->vm86 = (flags >> VM_SHIFT) & 1;
7754
    dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
7755
    dc->iopl = (flags >> IOPL_SHIFT) & 3;
7756
    dc->tf = (flags >> TF_SHIFT) & 1;
7757
    dc->singlestep_enabled = env->singlestep_enabled;
7758
    dc->cc_op = CC_OP_DYNAMIC;
7759
    dc->cs_base = cs_base;
7760
    dc->tb = tb;
7761
    dc->popl_esp_hack = 0;
7762
    /* select memory access functions */
7763
    dc->mem_index = 0;
7764
    if (flags & HF_SOFTMMU_MASK) {
7765
        if (dc->cpl == 3)
7766
            dc->mem_index = 2 * 4;
7767
        else
7768
            dc->mem_index = 1 * 4;
7769
    }
7770
    dc->cpuid_features = env->cpuid_features;
7771
    dc->cpuid_ext_features = env->cpuid_ext_features;
7772
    dc->cpuid_ext2_features = env->cpuid_ext2_features;
7773
    dc->cpuid_ext3_features = env->cpuid_ext3_features;
7774
#ifdef TARGET_X86_64
7775
    dc->lma = (flags >> HF_LMA_SHIFT) & 1;
7776
    dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
7777
#endif
7778
    dc->flags = flags;
7779
    dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
7780
                    (flags & HF_INHIBIT_IRQ_MASK)
7781
#ifndef CONFIG_SOFTMMU
7782
                    || (flags & HF_SOFTMMU_MASK)
7783
#endif
7784
                    );
7785
#if 0
7786
    /* check addseg logic */
7787
    if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
7788
        printf("ERROR addseg\n");
7789
#endif
7790

    
7791
    cpu_T[0] = tcg_temp_new();
7792
    cpu_T[1] = tcg_temp_new();
7793
    cpu_A0 = tcg_temp_new();
7794
    cpu_T3 = tcg_temp_new();
7795

    
7796
    cpu_tmp0 = tcg_temp_new();
7797
    cpu_tmp1_i64 = tcg_temp_new_i64();
7798
    cpu_tmp2_i32 = tcg_temp_new_i32();
7799
    cpu_tmp3_i32 = tcg_temp_new_i32();
7800
    cpu_tmp4 = tcg_temp_new();
7801
    cpu_tmp5 = tcg_temp_new();
7802
    cpu_ptr0 = tcg_temp_new_ptr();
7803
    cpu_ptr1 = tcg_temp_new_ptr();
7804

    
7805
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
7806

    
7807
    dc->is_jmp = DISAS_NEXT;
7808
    pc_ptr = pc_start;
7809
    lj = -1;
7810
    num_insns = 0;
7811
    max_insns = tb->cflags & CF_COUNT_MASK;
7812
    if (max_insns == 0)
7813
        max_insns = CF_COUNT_MASK;
7814

    
7815
    gen_icount_start();
7816
    for(;;) {
7817
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
7818
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
7819
                if (bp->pc == pc_ptr &&
7820
                    !((bp->flags & BP_CPU) && (tb->flags & HF_RF_MASK))) {
7821
                    gen_debug(dc, pc_ptr - dc->cs_base);
7822
                    break;
7823
                }
7824
            }
7825
        }
7826
        if (search_pc) {
7827
            j = gen_opc_ptr - gen_opc_buf;
7828
            if (lj < j) {
7829
                lj++;
7830
                while (lj < j)
7831
                    gen_opc_instr_start[lj++] = 0;
7832
            }
7833
            gen_opc_pc[lj] = pc_ptr;
7834
            gen_opc_cc_op[lj] = dc->cc_op;
7835
            gen_opc_instr_start[lj] = 1;
7836
            gen_opc_icount[lj] = num_insns;
7837
        }
7838
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
7839
            gen_io_start();
7840

    
7841
        pc_ptr = disas_insn(dc, pc_ptr);
7842
        num_insns++;
7843
        /* stop translation if indicated */
7844
        if (dc->is_jmp)
7845
            break;
7846
        /* if single step mode, we generate only one instruction and
7847
           generate an exception */
7848
        /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
7849
           the flag and abort the translation to give the irqs a
7850
           change to be happen */
7851
        if (dc->tf || dc->singlestep_enabled ||
7852
            (flags & HF_INHIBIT_IRQ_MASK)) {
7853
            gen_jmp_im(pc_ptr - dc->cs_base);
7854
            gen_eob(dc);
7855
            break;
7856
        }
7857
        /* if too long translation, stop generation too */
7858
        if (gen_opc_ptr >= gen_opc_end ||
7859
            (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32) ||
7860
            num_insns >= max_insns) {
7861
            gen_jmp_im(pc_ptr - dc->cs_base);
7862
            gen_eob(dc);
7863
            break;
7864
        }
7865
        if (singlestep) {
7866
            gen_jmp_im(pc_ptr - dc->cs_base);
7867
            gen_eob(dc);
7868
            break;
7869
        }
7870
    }
7871
    if (tb->cflags & CF_LAST_IO)
7872
        gen_io_end();
7873
    gen_icount_end(tb, num_insns);
7874
    *gen_opc_ptr = INDEX_op_end;
7875
    /* we don't forget to fill the last values */
7876
    if (search_pc) {
7877
        j = gen_opc_ptr - gen_opc_buf;
7878
        lj++;
7879
        while (lj <= j)
7880
            gen_opc_instr_start[lj++] = 0;
7881
    }
7882

    
7883
#ifdef DEBUG_DISAS
7884
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
7885
        int disas_flags;
7886
        qemu_log("----------------\n");
7887
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
7888
#ifdef TARGET_X86_64
7889
        if (dc->code64)
7890
            disas_flags = 2;
7891
        else
7892
#endif
7893
            disas_flags = !dc->code32;
7894
        log_target_disas(pc_start, pc_ptr - pc_start, disas_flags);
7895
        qemu_log("\n");
7896
    }
7897
#endif
7898

    
7899
    if (!search_pc) {
7900
        tb->size = pc_ptr - pc_start;
7901
        tb->icount = num_insns;
7902
    }
7903
}
7904

    
7905
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
7906
{
7907
    gen_intermediate_code_internal(env, tb, 0);
7908
}
7909

    
7910
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
7911
{
7912
    gen_intermediate_code_internal(env, tb, 1);
7913
}
7914

    
7915
void gen_pc_load(CPUState *env, TranslationBlock *tb,
7916
                unsigned long searched_pc, int pc_pos, void *puc)
7917
{
7918
    int cc_op;
7919
#ifdef DEBUG_DISAS
7920
    if (qemu_loglevel_mask(CPU_LOG_TB_OP)) {
7921
        int i;
7922
        qemu_log("RESTORE:\n");
7923
        for(i = 0;i <= pc_pos; i++) {
7924
            if (gen_opc_instr_start[i]) {
7925
                qemu_log("0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]);
7926
            }
7927
        }
7928
        qemu_log("spc=0x%08lx pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
7929
                searched_pc, pc_pos, gen_opc_pc[pc_pos] - tb->cs_base,
7930
                (uint32_t)tb->cs_base);
7931
    }
7932
#endif
7933
    env->eip = gen_opc_pc[pc_pos] - tb->cs_base;
7934
    cc_op = gen_opc_cc_op[pc_pos];
7935
    if (cc_op != CC_OP_DYNAMIC)
7936
        env->cc_op = cc_op;
7937
}