Statistics
| Branch: | Revision:

root / target-i386 / translate.c @ 1e4840bf

History | View | Annotate | Download (236.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, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20
#include <stdarg.h>
21
#include <stdlib.h>
22
#include <stdio.h>
23
#include <string.h>
24
#include <inttypes.h>
25
#include <signal.h>
26
#include <assert.h>
27

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

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

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

    
58
//#define MACRO_TEST   1
59

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

    
68
#ifdef TARGET_X86_64
69
static int x86_64_hregs;
70
#endif
71

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

    
110
static void gen_eob(DisasContext *s);
111
static void gen_jmp(DisasContext *s, target_ulong eip);
112
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
113

    
114
/* i386 arith/logic operations */
115
enum {
116
    OP_ADDL,
117
    OP_ORL,
118
    OP_ADCL,
119
    OP_SBBL,
120
    OP_ANDL,
121
    OP_SUBL,
122
    OP_XORL,
123
    OP_CMPL,
124
};
125

    
126
/* i386 shift ops */
127
enum {
128
    OP_ROL,
129
    OP_ROR,
130
    OP_RCL,
131
    OP_RCR,
132
    OP_SHL,
133
    OP_SHR,
134
    OP_SHL1, /* undocumented */
135
    OP_SAR = 7,
136
};
137

    
138
enum {
139
    JCC_O,
140
    JCC_B,
141
    JCC_Z,
142
    JCC_BE,
143
    JCC_S,
144
    JCC_P,
145
    JCC_L,
146
    JCC_LE,
147
};
148

    
149
/* operand size */
150
enum {
151
    OT_BYTE = 0,
152
    OT_WORD,
153
    OT_LONG,
154
    OT_QUAD,
155
};
156

    
157
enum {
158
    /* I386 int registers */
159
    OR_EAX,   /* MUST be even numbered */
160
    OR_ECX,
161
    OR_EDX,
162
    OR_EBX,
163
    OR_ESP,
164
    OR_EBP,
165
    OR_ESI,
166
    OR_EDI,
167

    
168
    OR_TMP0 = 16,    /* temporary operand register */
169
    OR_TMP1,
170
    OR_A0, /* temporary register used when doing address evaluation */
171
};
172

    
173
static inline void gen_op_movl_T0_0(void)
174
{
175
    tcg_gen_movi_tl(cpu_T[0], 0);
176
}
177

    
178
static inline void gen_op_movl_T0_im(int32_t val)
179
{
180
    tcg_gen_movi_tl(cpu_T[0], val);
181
}
182

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

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

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

    
198
static inline void gen_op_movl_A0_im(uint32_t val)
199
{
200
    tcg_gen_movi_tl(cpu_A0, val);
201
}
202

    
203
#ifdef TARGET_X86_64
204
static inline void gen_op_movq_A0_im(int64_t val)
205
{
206
    tcg_gen_movi_tl(cpu_A0, val);
207
}
208
#endif
209

    
210
static inline void gen_movtl_T0_im(target_ulong val)
211
{
212
    tcg_gen_movi_tl(cpu_T[0], val);
213
}
214

    
215
static inline void gen_movtl_T1_im(target_ulong val)
216
{
217
    tcg_gen_movi_tl(cpu_T[1], val);
218
}
219

    
220
static inline void gen_op_andl_T0_ffff(void)
221
{
222
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
223
}
224

    
225
static inline void gen_op_andl_T0_im(uint32_t val)
226
{
227
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], val);
228
}
229

    
230
static inline void gen_op_movl_T0_T1(void)
231
{
232
    tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
233
}
234

    
235
static inline void gen_op_andl_A0_ffff(void)
236
{
237
    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffff);
238
}
239

    
240
#ifdef TARGET_X86_64
241

    
242
#define NB_OP_SIZES 4
243

    
244
#else /* !TARGET_X86_64 */
245

    
246
#define NB_OP_SIZES 3
247

    
248
#endif /* !TARGET_X86_64 */
249

    
250
#if defined(WORDS_BIGENDIAN)
251
#define REG_B_OFFSET (sizeof(target_ulong) - 1)
252
#define REG_H_OFFSET (sizeof(target_ulong) - 2)
253
#define REG_W_OFFSET (sizeof(target_ulong) - 2)
254
#define REG_L_OFFSET (sizeof(target_ulong) - 4)
255
#define REG_LH_OFFSET (sizeof(target_ulong) - 8)
256
#else
257
#define REG_B_OFFSET 0
258
#define REG_H_OFFSET 1
259
#define REG_W_OFFSET 0
260
#define REG_L_OFFSET 0
261
#define REG_LH_OFFSET 4
262
#endif
263

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

    
297
static inline void gen_op_mov_reg_T0(int ot, int reg)
298
{
299
    gen_op_mov_reg_v(ot, reg, cpu_T[0]);
300
}
301

    
302
static inline void gen_op_mov_reg_T1(int ot, int reg)
303
{
304
    gen_op_mov_reg_v(ot, reg, cpu_T[1]);
305
}
306

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

    
333
static inline void gen_op_mov_v_reg(int ot, TCGv t0, int reg)
334
{
335
    switch(ot) {
336
    case OT_BYTE:
337
        if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
338
            goto std_case;
339
        } else {
340
            tcg_gen_ld8u_tl(t0, cpu_env, offsetof(CPUState, regs[reg - 4]) + REG_H_OFFSET);
341
        }
342
        break;
343
    default:
344
    std_case:
345
        tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, regs[reg]));
346
        break;
347
    }
348
}
349

    
350
static inline void gen_op_mov_TN_reg(int ot, int t_index, int reg)
351
{
352
    gen_op_mov_v_reg(ot, cpu_T[t_index], reg);
353
}
354

    
355
static inline void gen_op_movl_A0_reg(int reg)
356
{
357
    tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
358
}
359

    
360
static inline void gen_op_addl_A0_im(int32_t val)
361
{
362
    tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
363
#ifdef TARGET_X86_64
364
    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
365
#endif
366
}
367

    
368
#ifdef TARGET_X86_64
369
static inline void gen_op_addq_A0_im(int64_t val)
370
{
371
    tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
372
}
373
#endif
374
    
375
static void gen_add_A0_im(DisasContext *s, int val)
376
{
377
#ifdef TARGET_X86_64
378
    if (CODE64(s))
379
        gen_op_addq_A0_im(val);
380
    else
381
#endif
382
        gen_op_addl_A0_im(val);
383
}
384

    
385
static inline void gen_op_addl_T0_T1(void)
386
{
387
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
388
}
389

    
390
static inline void gen_op_jmp_T0(void)
391
{
392
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, eip));
393
}
394

    
395
static inline void gen_op_add_reg_im(int size, int reg, int32_t val)
396
{
397
    switch(size) {
398
    case 0:
399
        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
400
        tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val);
401
        tcg_gen_st16_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_W_OFFSET);
402
        break;
403
    case 1:
404
        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
405
        tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val);
406
#ifdef TARGET_X86_64
407
        tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff);
408
#endif
409
        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
410
        break;
411
#ifdef TARGET_X86_64
412
    case 2:
413
        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
414
        tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val);
415
        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
416
        break;
417
#endif
418
    }
419
}
420

    
421
static inline void gen_op_add_reg_T0(int size, int reg)
422
{
423
    switch(size) {
424
    case 0:
425
        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
426
        tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]);
427
        tcg_gen_st16_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_W_OFFSET);
428
        break;
429
    case 1:
430
        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
431
        tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]);
432
#ifdef TARGET_X86_64
433
        tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff);
434
#endif
435
        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
436
        break;
437
#ifdef TARGET_X86_64
438
    case 2:
439
        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
440
        tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]);
441
        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
442
        break;
443
#endif
444
    }
445
}
446

    
447
static inline void gen_op_set_cc_op(int32_t val)
448
{
449
    tcg_gen_movi_i32(cpu_cc_op, val);
450
}
451

    
452
static inline void gen_op_addl_A0_reg_sN(int shift, int reg)
453
{
454
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
455
    if (shift != 0) 
456
        tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
457
    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
458
#ifdef TARGET_X86_64
459
    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
460
#endif
461
}
462

    
463
static inline void gen_op_movl_A0_seg(int reg)
464
{
465
    tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUState, segs[reg].base) + REG_L_OFFSET);
466
}
467

    
468
static inline void gen_op_addl_A0_seg(int reg)
469
{
470
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, segs[reg].base));
471
    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
472
#ifdef TARGET_X86_64
473
    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
474
#endif
475
}
476

    
477
#ifdef TARGET_X86_64
478
static inline void gen_op_movq_A0_seg(int reg)
479
{
480
    tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUState, segs[reg].base));
481
}
482

    
483
static inline void gen_op_addq_A0_seg(int reg)
484
{
485
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, segs[reg].base));
486
    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
487
}
488

    
489
static inline void gen_op_movq_A0_reg(int reg)
490
{
491
    tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]));
492
}
493

    
494
static inline void gen_op_addq_A0_reg_sN(int shift, int reg)
495
{
496
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
497
    if (shift != 0) 
498
        tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
499
    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
500
}
501
#endif
502

    
503
static inline void gen_op_lds_T0_A0(int idx)
504
{
505
    int mem_index = (idx >> 2) - 1;
506
    switch(idx & 3) {
507
    case 0:
508
        tcg_gen_qemu_ld8s(cpu_T[0], cpu_A0, mem_index);
509
        break;
510
    case 1:
511
        tcg_gen_qemu_ld16s(cpu_T[0], cpu_A0, mem_index);
512
        break;
513
    default:
514
    case 2:
515
        tcg_gen_qemu_ld32s(cpu_T[0], cpu_A0, mem_index);
516
        break;
517
    }
518
}
519

    
520
static inline void gen_op_ld_v(int idx, TCGv t0, TCGv a0)
521
{
522
    int mem_index = (idx >> 2) - 1;
523
    switch(idx & 3) {
524
    case 0:
525
        tcg_gen_qemu_ld8u(t0, a0, mem_index);
526
        break;
527
    case 1:
528
        tcg_gen_qemu_ld16u(t0, a0, mem_index);
529
        break;
530
    case 2:
531
        tcg_gen_qemu_ld32u(t0, a0, mem_index);
532
        break;
533
    default:
534
    case 3:
535
        tcg_gen_qemu_ld64(t0, a0, mem_index);
536
        break;
537
    }
538
}
539

    
540
/* XXX: always use ldu or lds */
541
static inline void gen_op_ld_T0_A0(int idx)
542
{
543
    gen_op_ld_v(idx, cpu_T[0], cpu_A0);
544
}
545

    
546
static inline void gen_op_ldu_T0_A0(int idx)
547
{
548
    gen_op_ld_v(idx, cpu_T[0], cpu_A0);
549
}
550

    
551
static inline void gen_op_ld_T1_A0(int idx)
552
{
553
    gen_op_ld_v(idx, cpu_T[1], cpu_A0);
554
}
555

    
556
static inline void gen_op_st_v(int idx, TCGv t0, TCGv a0)
557
{
558
    int mem_index = (idx >> 2) - 1;
559
    switch(idx & 3) {
560
    case 0:
561
        tcg_gen_qemu_st8(t0, a0, mem_index);
562
        break;
563
    case 1:
564
        tcg_gen_qemu_st16(t0, a0, mem_index);
565
        break;
566
    case 2:
567
        tcg_gen_qemu_st32(t0, a0, mem_index);
568
        break;
569
    default:
570
    case 3:
571
        tcg_gen_qemu_st64(t0, a0, mem_index);
572
        break;
573
    }
574
}
575

    
576
static inline void gen_op_st_T0_A0(int idx)
577
{
578
    gen_op_st_v(idx, cpu_T[0], cpu_A0);
579
}
580

    
581
static inline void gen_op_st_T1_A0(int idx)
582
{
583
    gen_op_st_v(idx, cpu_T[1], cpu_A0);
584
}
585

    
586
static inline void gen_jmp_im(target_ulong pc)
587
{
588
    tcg_gen_movi_tl(cpu_tmp0, pc);
589
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, eip));
590
}
591

    
592
static inline void gen_string_movl_A0_ESI(DisasContext *s)
593
{
594
    int override;
595

    
596
    override = s->override;
597
#ifdef TARGET_X86_64
598
    if (s->aflag == 2) {
599
        if (override >= 0) {
600
            gen_op_movq_A0_seg(override);
601
            gen_op_addq_A0_reg_sN(0, R_ESI);
602
        } else {
603
            gen_op_movq_A0_reg(R_ESI);
604
        }
605
    } else
606
#endif
607
    if (s->aflag) {
608
        /* 32 bit address */
609
        if (s->addseg && override < 0)
610
            override = R_DS;
611
        if (override >= 0) {
612
            gen_op_movl_A0_seg(override);
613
            gen_op_addl_A0_reg_sN(0, R_ESI);
614
        } else {
615
            gen_op_movl_A0_reg(R_ESI);
616
        }
617
    } else {
618
        /* 16 address, always override */
619
        if (override < 0)
620
            override = R_DS;
621
        gen_op_movl_A0_reg(R_ESI);
622
        gen_op_andl_A0_ffff();
623
        gen_op_addl_A0_seg(override);
624
    }
625
}
626

    
627
static inline void gen_string_movl_A0_EDI(DisasContext *s)
628
{
629
#ifdef TARGET_X86_64
630
    if (s->aflag == 2) {
631
        gen_op_movq_A0_reg(R_EDI);
632
    } else
633
#endif
634
    if (s->aflag) {
635
        if (s->addseg) {
636
            gen_op_movl_A0_seg(R_ES);
637
            gen_op_addl_A0_reg_sN(0, R_EDI);
638
        } else {
639
            gen_op_movl_A0_reg(R_EDI);
640
        }
641
    } else {
642
        gen_op_movl_A0_reg(R_EDI);
643
        gen_op_andl_A0_ffff();
644
        gen_op_addl_A0_seg(R_ES);
645
    }
646
}
647

    
648
static inline void gen_op_movl_T0_Dshift(int ot) 
649
{
650
    tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUState, df));
651
    tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot);
652
};
653

    
654
static void gen_extu(int ot, TCGv reg)
655
{
656
    switch(ot) {
657
    case OT_BYTE:
658
        tcg_gen_ext8u_tl(reg, reg);
659
        break;
660
    case OT_WORD:
661
        tcg_gen_ext16u_tl(reg, reg);
662
        break;
663
    case OT_LONG:
664
        tcg_gen_ext32u_tl(reg, reg);
665
        break;
666
    default:
667
        break;
668
    }
669
}
670

    
671
static void gen_exts(int ot, TCGv reg)
672
{
673
    switch(ot) {
674
    case OT_BYTE:
675
        tcg_gen_ext8s_tl(reg, reg);
676
        break;
677
    case OT_WORD:
678
        tcg_gen_ext16s_tl(reg, reg);
679
        break;
680
    case OT_LONG:
681
        tcg_gen_ext32s_tl(reg, reg);
682
        break;
683
    default:
684
        break;
685
    }
686
}
687

    
688
static inline void gen_op_jnz_ecx(int size, int label1)
689
{
690
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ECX]));
691
    gen_extu(size + 1, cpu_tmp0);
692
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
693
}
694

    
695
static inline void gen_op_jz_ecx(int size, int label1)
696
{
697
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ECX]));
698
    gen_extu(size + 1, cpu_tmp0);
699
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
700
}
701

    
702
static void *helper_in_func[3] = {
703
    helper_inb,
704
    helper_inw,
705
    helper_inl,
706
};
707

    
708
static void *helper_out_func[3] = {
709
    helper_outb,
710
    helper_outw,
711
    helper_outl,
712
};
713

    
714
static void *gen_check_io_func[3] = {
715
    helper_check_iob,
716
    helper_check_iow,
717
    helper_check_iol,
718
};
719

    
720
static void gen_check_io(DisasContext *s, int ot, target_ulong cur_eip,
721
                         uint32_t svm_flags)
722
{
723
    int state_saved;
724
    target_ulong next_eip;
725

    
726
    state_saved = 0;
727
    if (s->pe && (s->cpl > s->iopl || s->vm86)) {
728
        if (s->cc_op != CC_OP_DYNAMIC)
729
            gen_op_set_cc_op(s->cc_op);
730
        gen_jmp_im(cur_eip);
731
        state_saved = 1;
732
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
733
        tcg_gen_helper_0_1(gen_check_io_func[ot],
734
                           cpu_tmp2_i32);
735
    }
736
    if(s->flags & (1ULL << INTERCEPT_IOIO_PROT)) {
737
        if (!state_saved) {
738
            if (s->cc_op != CC_OP_DYNAMIC)
739
                gen_op_set_cc_op(s->cc_op);
740
            gen_jmp_im(cur_eip);
741
            state_saved = 1;
742
        }
743
        svm_flags |= (1 << (4 + ot));
744
        next_eip = s->pc - s->cs_base;
745
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
746
        tcg_gen_helper_0_3(helper_svm_check_io,
747
                           cpu_tmp2_i32,
748
                           tcg_const_i32(svm_flags),
749
                           tcg_const_i32(next_eip - cur_eip));
750
    }
751
}
752

    
753
static inline void gen_movs(DisasContext *s, int ot)
754
{
755
    gen_string_movl_A0_ESI(s);
756
    gen_op_ld_T0_A0(ot + s->mem_index);
757
    gen_string_movl_A0_EDI(s);
758
    gen_op_st_T0_A0(ot + s->mem_index);
759
    gen_op_movl_T0_Dshift(ot);
760
    gen_op_add_reg_T0(s->aflag, R_ESI);
761
    gen_op_add_reg_T0(s->aflag, R_EDI);
762
}
763

    
764
static inline void gen_update_cc_op(DisasContext *s)
765
{
766
    if (s->cc_op != CC_OP_DYNAMIC) {
767
        gen_op_set_cc_op(s->cc_op);
768
        s->cc_op = CC_OP_DYNAMIC;
769
    }
770
}
771

    
772
static void gen_op_update1_cc(void)
773
{
774
    tcg_gen_discard_tl(cpu_cc_src);
775
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
776
}
777

    
778
static void gen_op_update2_cc(void)
779
{
780
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
781
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
782
}
783

    
784
static inline void gen_op_cmpl_T0_T1_cc(void)
785
{
786
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
787
    tcg_gen_sub_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
788
}
789

    
790
static inline void gen_op_testl_T0_T1_cc(void)
791
{
792
    tcg_gen_discard_tl(cpu_cc_src);
793
    tcg_gen_and_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
794
}
795

    
796
static void gen_op_update_neg_cc(void)
797
{
798
    tcg_gen_neg_tl(cpu_cc_src, cpu_T[0]);
799
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
800
}
801

    
802
/* compute eflags.C to reg */
803
static void gen_compute_eflags_c(TCGv reg)
804
{
805
#if TCG_TARGET_REG_BITS == 32
806
    tcg_gen_shli_i32(cpu_tmp2_i32, cpu_cc_op, 3);
807
    tcg_gen_addi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 
808
                     (long)cc_table + offsetof(CCTable, compute_c));
809
    tcg_gen_ld_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0);
810
    tcg_gen_call(&tcg_ctx, cpu_tmp2_i32, TCG_CALL_PURE, 
811
                 1, &cpu_tmp2_i32, 0, NULL);
812
#else
813
    tcg_gen_extu_i32_tl(cpu_tmp1_i64, cpu_cc_op);
814
    tcg_gen_shli_i64(cpu_tmp1_i64, cpu_tmp1_i64, 4);
815
    tcg_gen_addi_i64(cpu_tmp1_i64, cpu_tmp1_i64, 
816
                     (long)cc_table + offsetof(CCTable, compute_c));
817
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_tmp1_i64, 0);
818
    tcg_gen_call(&tcg_ctx, cpu_tmp1_i64, TCG_CALL_PURE, 
819
                 1, &cpu_tmp2_i32, 0, NULL);
820
#endif
821
    tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);
822
}
823

    
824
/* compute all eflags to cc_src */
825
static void gen_compute_eflags(TCGv reg)
826
{
827
#if TCG_TARGET_REG_BITS == 32
828
    tcg_gen_shli_i32(cpu_tmp2_i32, cpu_cc_op, 3);
829
    tcg_gen_addi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 
830
                     (long)cc_table + offsetof(CCTable, compute_all));
831
    tcg_gen_ld_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0);
832
    tcg_gen_call(&tcg_ctx, cpu_tmp2_i32, TCG_CALL_PURE, 
833
                 1, &cpu_tmp2_i32, 0, NULL);
834
#else
835
    tcg_gen_extu_i32_tl(cpu_tmp1_i64, cpu_cc_op);
836
    tcg_gen_shli_i64(cpu_tmp1_i64, cpu_tmp1_i64, 4);
837
    tcg_gen_addi_i64(cpu_tmp1_i64, cpu_tmp1_i64, 
838
                     (long)cc_table + offsetof(CCTable, compute_all));
839
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_tmp1_i64, 0);
840
    tcg_gen_call(&tcg_ctx, cpu_tmp1_i64, TCG_CALL_PURE, 
841
                 1, &cpu_tmp2_i32, 0, NULL);
842
#endif
843
    tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);
844
}
845

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

    
900
/* return true if setcc_slow is not needed (WARNING: must be kept in
901
   sync with gen_jcc1) */
902
static int is_fast_jcc_case(DisasContext *s, int b)
903
{
904
    int jcc_op;
905
    jcc_op = (b >> 1) & 7;
906
    switch(s->cc_op) {
907
        /* we optimize the cmp/jcc case */
908
    case CC_OP_SUBB:
909
    case CC_OP_SUBW:
910
    case CC_OP_SUBL:
911
    case CC_OP_SUBQ:
912
        if (jcc_op == JCC_O || jcc_op == JCC_P)
913
            goto slow_jcc;
914
        break;
915

    
916
        /* some jumps are easy to compute */
917
    case CC_OP_ADDB:
918
    case CC_OP_ADDW:
919
    case CC_OP_ADDL:
920
    case CC_OP_ADDQ:
921

    
922
    case CC_OP_LOGICB:
923
    case CC_OP_LOGICW:
924
    case CC_OP_LOGICL:
925
    case CC_OP_LOGICQ:
926

    
927
    case CC_OP_INCB:
928
    case CC_OP_INCW:
929
    case CC_OP_INCL:
930
    case CC_OP_INCQ:
931

    
932
    case CC_OP_DECB:
933
    case CC_OP_DECW:
934
    case CC_OP_DECL:
935
    case CC_OP_DECQ:
936

    
937
    case CC_OP_SHLB:
938
    case CC_OP_SHLW:
939
    case CC_OP_SHLL:
940
    case CC_OP_SHLQ:
941
        if (jcc_op != JCC_Z && jcc_op != JCC_S)
942
            goto slow_jcc;
943
        break;
944
    default:
945
    slow_jcc:
946
        return 0;
947
    }
948
    return 1;
949
}
950

    
951
/* generate a conditional jump to label 'l1' according to jump opcode
952
   value 'b'. In the fast case, T0 is guaranted not to be used. */
953
static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1)
954
{
955
    int inv, jcc_op, size, cond;
956
    TCGv t0;
957

    
958
    inv = b & 1;
959
    jcc_op = (b >> 1) & 7;
960

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

    
1149
/* XXX: does not work with gdbstub "ice" single step - not a
1150
   serious problem */
1151
static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
1152
{
1153
    int l1, l2;
1154

    
1155
    l1 = gen_new_label();
1156
    l2 = gen_new_label();
1157
    gen_op_jnz_ecx(s->aflag, l1);
1158
    gen_set_label(l2);
1159
    gen_jmp_tb(s, next_eip, 1);
1160
    gen_set_label(l1);
1161
    return l2;
1162
}
1163

    
1164
static inline void gen_stos(DisasContext *s, int ot)
1165
{
1166
    gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
1167
    gen_string_movl_A0_EDI(s);
1168
    gen_op_st_T0_A0(ot + s->mem_index);
1169
    gen_op_movl_T0_Dshift(ot);
1170
    gen_op_add_reg_T0(s->aflag, R_EDI);
1171
}
1172

    
1173
static inline void gen_lods(DisasContext *s, int ot)
1174
{
1175
    gen_string_movl_A0_ESI(s);
1176
    gen_op_ld_T0_A0(ot + s->mem_index);
1177
    gen_op_mov_reg_T0(ot, R_EAX);
1178
    gen_op_movl_T0_Dshift(ot);
1179
    gen_op_add_reg_T0(s->aflag, R_ESI);
1180
}
1181

    
1182
static inline void gen_scas(DisasContext *s, int ot)
1183
{
1184
    gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
1185
    gen_string_movl_A0_EDI(s);
1186
    gen_op_ld_T1_A0(ot + s->mem_index);
1187
    gen_op_cmpl_T0_T1_cc();
1188
    gen_op_movl_T0_Dshift(ot);
1189
    gen_op_add_reg_T0(s->aflag, R_EDI);
1190
}
1191

    
1192
static inline void gen_cmps(DisasContext *s, int ot)
1193
{
1194
    gen_string_movl_A0_ESI(s);
1195
    gen_op_ld_T0_A0(ot + s->mem_index);
1196
    gen_string_movl_A0_EDI(s);
1197
    gen_op_ld_T1_A0(ot + s->mem_index);
1198
    gen_op_cmpl_T0_T1_cc();
1199
    gen_op_movl_T0_Dshift(ot);
1200
    gen_op_add_reg_T0(s->aflag, R_ESI);
1201
    gen_op_add_reg_T0(s->aflag, R_EDI);
1202
}
1203

    
1204
static inline void gen_ins(DisasContext *s, int ot)
1205
{
1206
    gen_string_movl_A0_EDI(s);
1207
    /* Note: we must do this dummy write first to be restartable in
1208
       case of page fault. */
1209
    gen_op_movl_T0_0();
1210
    gen_op_st_T0_A0(ot + s->mem_index);
1211
    gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
1212
    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
1213
    tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1214
    tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[0], cpu_tmp2_i32);
1215
    gen_op_st_T0_A0(ot + s->mem_index);
1216
    gen_op_movl_T0_Dshift(ot);
1217
    gen_op_add_reg_T0(s->aflag, R_EDI);
1218
}
1219

    
1220
static inline void gen_outs(DisasContext *s, int ot)
1221
{
1222
    gen_string_movl_A0_ESI(s);
1223
    gen_op_ld_T0_A0(ot + s->mem_index);
1224

    
1225
    gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
1226
    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
1227
    tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1228
    tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]);
1229
    tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2_i32, cpu_tmp3_i32);
1230

    
1231
    gen_op_movl_T0_Dshift(ot);
1232
    gen_op_add_reg_T0(s->aflag, R_ESI);
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 *helper_fp_arith_ST0_FT0[8] = {
1280
    helper_fadd_ST0_FT0,
1281
    helper_fmul_ST0_FT0,
1282
    helper_fcom_ST0_FT0,
1283
    helper_fcom_ST0_FT0,
1284
    helper_fsub_ST0_FT0,
1285
    helper_fsubr_ST0_FT0,
1286
    helper_fdiv_ST0_FT0,
1287
    helper_fdivr_ST0_FT0,
1288
};
1289

    
1290
/* NOTE the exception in "r" op ordering */
1291
static void *helper_fp_arith_STN_ST0[8] = {
1292
    helper_fadd_STN_ST0,
1293
    helper_fmul_STN_ST0,
1294
    NULL,
1295
    NULL,
1296
    helper_fsubr_STN_ST0,
1297
    helper_fsub_STN_ST0,
1298
    helper_fdivr_STN_ST0,
1299
    helper_fdiv_STN_ST0,
1300
};
1301

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1581
    tcg_gen_andi_tl(t1, t1, mask);
1582

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

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

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

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

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

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

    
1649
static void *helper_rotc[8] = {
1650
    helper_rclb,
1651
    helper_rclw,
1652
    helper_rcll,
1653
    X86_64_ONLY(helper_rclq),
1654
    helper_rcrb,
1655
    helper_rcrw,
1656
    helper_rcrl,
1657
    X86_64_ONLY(helper_rcrq),
1658
};
1659

    
1660
/* XXX: add faster immediate = 1 case */
1661
static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, 
1662
                           int is_right)
1663
{
1664
    int label1;
1665

    
1666
    if (s->cc_op != CC_OP_DYNAMIC)
1667
        gen_op_set_cc_op(s->cc_op);
1668

    
1669
    /* load */
1670
    if (op1 == OR_TMP0)
1671
        gen_op_ld_T0_A0(ot + s->mem_index);
1672
    else
1673
        gen_op_mov_TN_reg(ot, 0, op1);
1674
    
1675
    tcg_gen_helper_1_2(helper_rotc[ot + (is_right * 4)],
1676
                       cpu_T[0], cpu_T[0], cpu_T[1]);
1677
    /* store */
1678
    if (op1 == OR_TMP0)
1679
        gen_op_st_T0_A0(ot + s->mem_index);
1680
    else
1681
        gen_op_mov_reg_T0(ot, op1);
1682

    
1683
    /* update eflags */
1684
    label1 = gen_new_label();
1685
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cc_tmp, -1, label1);
1686

    
1687
    tcg_gen_mov_tl(cpu_cc_src, cpu_cc_tmp);
1688
    tcg_gen_discard_tl(cpu_cc_dst);
1689
    tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
1690
        
1691
    gen_set_label(label1);
1692
    s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1693
}
1694

    
1695
/* XXX: add faster immediate case */
1696
static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1, 
1697
                                int is_right)
1698
{
1699
    int label1, label2, data_bits;
1700
    target_ulong mask;
1701
    TCGv t0, t1, t2, a0;
1702

    
1703
    t0 = tcg_temp_local_new(TCG_TYPE_TL);
1704
    t1 = tcg_temp_local_new(TCG_TYPE_TL);
1705
    t2 = tcg_temp_local_new(TCG_TYPE_TL);
1706
    a0 = tcg_temp_local_new(TCG_TYPE_TL);
1707

    
1708
    if (ot == OT_QUAD)
1709
        mask = 0x3f;
1710
    else
1711
        mask = 0x1f;
1712

    
1713
    /* load */
1714
    if (op1 == OR_TMP0) {
1715
        tcg_gen_mov_tl(a0, cpu_A0);
1716
        gen_op_ld_v(ot + s->mem_index, t0, a0);
1717
    } else {
1718
        gen_op_mov_v_reg(ot, t0, op1);
1719
    }
1720

    
1721
    tcg_gen_andi_tl(cpu_T3, cpu_T3, mask);
1722

    
1723
    tcg_gen_mov_tl(t1, cpu_T[1]);
1724
    tcg_gen_mov_tl(t2, cpu_T3);
1725

    
1726
    /* Must test zero case to avoid using undefined behaviour in TCG
1727
       shifts. */
1728
    label1 = gen_new_label();
1729
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
1730
    
1731
    tcg_gen_addi_tl(cpu_tmp5, t2, -1);
1732
    if (ot == OT_WORD) {
1733
        /* Note: we implement the Intel behaviour for shift count > 16 */
1734
        if (is_right) {
1735
            tcg_gen_andi_tl(t0, t0, 0xffff);
1736
            tcg_gen_shli_tl(cpu_tmp0, t1, 16);
1737
            tcg_gen_or_tl(t0, t0, cpu_tmp0);
1738
            tcg_gen_ext32u_tl(t0, t0);
1739

    
1740
            tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
1741
            
1742
            /* only needed if count > 16, but a test would complicate */
1743
            tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(32), t2);
1744
            tcg_gen_shl_tl(cpu_tmp0, t0, cpu_tmp5);
1745

    
1746
            tcg_gen_shr_tl(t0, t0, t2);
1747

    
1748
            tcg_gen_or_tl(t0, t0, cpu_tmp0);
1749
        } else {
1750
            /* XXX: not optimal */
1751
            tcg_gen_andi_tl(t0, t0, 0xffff);
1752
            tcg_gen_shli_tl(t1, t1, 16);
1753
            tcg_gen_or_tl(t1, t1, t0);
1754
            tcg_gen_ext32u_tl(t1, t1);
1755
            
1756
            tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
1757
            tcg_gen_sub_tl(cpu_tmp0, tcg_const_tl(32), cpu_tmp5);
1758
            tcg_gen_shr_tl(cpu_tmp6, t1, cpu_tmp0);
1759
            tcg_gen_or_tl(cpu_tmp4, cpu_tmp4, cpu_tmp6);
1760

    
1761
            tcg_gen_shl_tl(t0, t0, t2);
1762
            tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(32), t2);
1763
            tcg_gen_shr_tl(t1, t1, cpu_tmp5);
1764
            tcg_gen_or_tl(t0, t0, t1);
1765
        }
1766
    } else {
1767
        data_bits = 8 << ot;
1768
        if (is_right) {
1769
            if (ot == OT_LONG)
1770
                tcg_gen_ext32u_tl(t0, t0);
1771

    
1772
            tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
1773

    
1774
            tcg_gen_shr_tl(t0, t0, t2);
1775
            tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(data_bits), t2);
1776
            tcg_gen_shl_tl(t1, t1, cpu_tmp5);
1777
            tcg_gen_or_tl(t0, t0, t1);
1778
            
1779
        } else {
1780
            if (ot == OT_LONG)
1781
                tcg_gen_ext32u_tl(t1, t1);
1782

    
1783
            tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
1784
            
1785
            tcg_gen_shl_tl(t0, t0, t2);
1786
            tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(data_bits), t2);
1787
            tcg_gen_shr_tl(t1, t1, cpu_tmp5);
1788
            tcg_gen_or_tl(t0, t0, t1);
1789
        }
1790
    }
1791
    tcg_gen_mov_tl(t1, cpu_tmp4);
1792

    
1793
    gen_set_label(label1);
1794
    /* store */
1795
    if (op1 == OR_TMP0) {
1796
        gen_op_st_v(ot + s->mem_index, t0, a0);
1797
    } else {
1798
        gen_op_mov_reg_v(ot, op1, t0);
1799
    }
1800
    
1801
    /* update eflags */
1802
    if (s->cc_op != CC_OP_DYNAMIC)
1803
        gen_op_set_cc_op(s->cc_op);
1804

    
1805
    label2 = gen_new_label();
1806
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label2);
1807

    
1808
    tcg_gen_mov_tl(cpu_cc_src, t1);
1809
    tcg_gen_mov_tl(cpu_cc_dst, t0);
1810
    if (is_right) {
1811
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
1812
    } else {
1813
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
1814
    }
1815
    gen_set_label(label2);
1816
    s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1817

    
1818
    tcg_temp_free(t0);
1819
    tcg_temp_free(t1);
1820
    tcg_temp_free(t2);
1821
    tcg_temp_free(a0);
1822
}
1823

    
1824
static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
1825
{
1826
    if (s != OR_TMP1)
1827
        gen_op_mov_TN_reg(ot, 1, s);
1828
    switch(op) {
1829
    case OP_ROL:
1830
        gen_rot_rm_T1(s1, ot, d, 0);
1831
        break;
1832
    case OP_ROR:
1833
        gen_rot_rm_T1(s1, ot, d, 1);
1834
        break;
1835
    case OP_SHL:
1836
    case OP_SHL1:
1837
        gen_shift_rm_T1(s1, ot, d, 0, 0);
1838
        break;
1839
    case OP_SHR:
1840
        gen_shift_rm_T1(s1, ot, d, 1, 0);
1841
        break;
1842
    case OP_SAR:
1843
        gen_shift_rm_T1(s1, ot, d, 1, 1);
1844
        break;
1845
    case OP_RCL:
1846
        gen_rotc_rm_T1(s1, ot, d, 0);
1847
        break;
1848
    case OP_RCR:
1849
        gen_rotc_rm_T1(s1, ot, d, 1);
1850
        break;
1851
    }
1852
}
1853

    
1854
static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
1855
{
1856
    switch(op) {
1857
    case OP_SHL:
1858
    case OP_SHL1:
1859
        gen_shift_rm_im(s1, ot, d, c, 0, 0);
1860
        break;
1861
    case OP_SHR:
1862
        gen_shift_rm_im(s1, ot, d, c, 1, 0);
1863
        break;
1864
    case OP_SAR:
1865
        gen_shift_rm_im(s1, ot, d, c, 1, 1);
1866
        break;
1867
    default:
1868
        /* currently not optimized */
1869
        gen_op_movl_T1_im(c);
1870
        gen_shift(s1, op, ot, d, OR_TMP1);
1871
        break;
1872
    }
1873
}
1874

    
1875
static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr)
1876
{
1877
    target_long disp;
1878
    int havesib;
1879
    int base;
1880
    int index;
1881
    int scale;
1882
    int opreg;
1883
    int mod, rm, code, override, must_add_seg;
1884

    
1885
    override = s->override;
1886
    must_add_seg = s->addseg;
1887
    if (override >= 0)
1888
        must_add_seg = 1;
1889
    mod = (modrm >> 6) & 3;
1890
    rm = modrm & 7;
1891

    
1892
    if (s->aflag) {
1893

    
1894
        havesib = 0;
1895
        base = rm;
1896
        index = 0;
1897
        scale = 0;
1898

    
1899
        if (base == 4) {
1900
            havesib = 1;
1901
            code = ldub_code(s->pc++);
1902
            scale = (code >> 6) & 3;
1903
            index = ((code >> 3) & 7) | REX_X(s);
1904
            base = (code & 7);
1905
        }
1906
        base |= REX_B(s);
1907

    
1908
        switch (mod) {
1909
        case 0:
1910
            if ((base & 7) == 5) {
1911
                base = -1;
1912
                disp = (int32_t)ldl_code(s->pc);
1913
                s->pc += 4;
1914
                if (CODE64(s) && !havesib) {
1915
                    disp += s->pc + s->rip_offset;
1916
                }
1917
            } else {
1918
                disp = 0;
1919
            }
1920
            break;
1921
        case 1:
1922
            disp = (int8_t)ldub_code(s->pc++);
1923
            break;
1924
        default:
1925
        case 2:
1926
            disp = ldl_code(s->pc);
1927
            s->pc += 4;
1928
            break;
1929
        }
1930

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

    
2053
    opreg = OR_A0;
2054
    disp = 0;
2055
    *reg_ptr = opreg;
2056
    *offset_ptr = disp;
2057
}
2058

    
2059
static void gen_nop_modrm(DisasContext *s, int modrm)
2060
{
2061
    int mod, rm, base, code;
2062

    
2063
    mod = (modrm >> 6) & 3;
2064
    if (mod == 3)
2065
        return;
2066
    rm = modrm & 7;
2067

    
2068
    if (s->aflag) {
2069

    
2070
        base = rm;
2071

    
2072
        if (base == 4) {
2073
            code = ldub_code(s->pc++);
2074
            base = (code & 7);
2075
        }
2076

    
2077
        switch (mod) {
2078
        case 0:
2079
            if (base == 5) {
2080
                s->pc += 4;
2081
            }
2082
            break;
2083
        case 1:
2084
            s->pc++;
2085
            break;
2086
        default:
2087
        case 2:
2088
            s->pc += 4;
2089
            break;
2090
        }
2091
    } else {
2092
        switch (mod) {
2093
        case 0:
2094
            if (rm == 6) {
2095
                s->pc += 2;
2096
            }
2097
            break;
2098
        case 1:
2099
            s->pc++;
2100
            break;
2101
        default:
2102
        case 2:
2103
            s->pc += 2;
2104
            break;
2105
        }
2106
    }
2107
}
2108

    
2109
/* used for LEA and MOV AX, mem */
2110
static void gen_add_A0_ds_seg(DisasContext *s)
2111
{
2112
    int override, must_add_seg;
2113
    must_add_seg = s->addseg;
2114
    override = R_DS;
2115
    if (s->override >= 0) {
2116
        override = s->override;
2117
        must_add_seg = 1;
2118
    } else {
2119
        override = R_DS;
2120
    }
2121
    if (must_add_seg) {
2122
#ifdef TARGET_X86_64
2123
        if (CODE64(s)) {
2124
            gen_op_addq_A0_seg(override);
2125
        } else
2126
#endif
2127
        {
2128
            gen_op_addl_A0_seg(override);
2129
        }
2130
    }
2131
}
2132

    
2133
/* generate modrm memory load or store of 'reg'. TMP0 is used if reg !=
2134
   OR_TMP0 */
2135
static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
2136
{
2137
    int mod, rm, opreg, disp;
2138

    
2139
    mod = (modrm >> 6) & 3;
2140
    rm = (modrm & 7) | REX_B(s);
2141
    if (mod == 3) {
2142
        if (is_store) {
2143
            if (reg != OR_TMP0)
2144
                gen_op_mov_TN_reg(ot, 0, reg);
2145
            gen_op_mov_reg_T0(ot, rm);
2146
        } else {
2147
            gen_op_mov_TN_reg(ot, 0, rm);
2148
            if (reg != OR_TMP0)
2149
                gen_op_mov_reg_T0(ot, reg);
2150
        }
2151
    } else {
2152
        gen_lea_modrm(s, modrm, &opreg, &disp);
2153
        if (is_store) {
2154
            if (reg != OR_TMP0)
2155
                gen_op_mov_TN_reg(ot, 0, reg);
2156
            gen_op_st_T0_A0(ot + s->mem_index);
2157
        } else {
2158
            gen_op_ld_T0_A0(ot + s->mem_index);
2159
            if (reg != OR_TMP0)
2160
                gen_op_mov_reg_T0(ot, reg);
2161
        }
2162
    }
2163
}
2164

    
2165
static inline uint32_t insn_get(DisasContext *s, int ot)
2166
{
2167
    uint32_t ret;
2168

    
2169
    switch(ot) {
2170
    case OT_BYTE:
2171
        ret = ldub_code(s->pc);
2172
        s->pc++;
2173
        break;
2174
    case OT_WORD:
2175
        ret = lduw_code(s->pc);
2176
        s->pc += 2;
2177
        break;
2178
    default:
2179
    case OT_LONG:
2180
        ret = ldl_code(s->pc);
2181
        s->pc += 4;
2182
        break;
2183
    }
2184
    return ret;
2185
}
2186

    
2187
static inline int insn_const_size(unsigned int ot)
2188
{
2189
    if (ot <= OT_LONG)
2190
        return 1 << ot;
2191
    else
2192
        return 4;
2193
}
2194

    
2195
static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
2196
{
2197
    TranslationBlock *tb;
2198
    target_ulong pc;
2199

    
2200
    pc = s->cs_base + eip;
2201
    tb = s->tb;
2202
    /* NOTE: we handle the case where the TB spans two pages here */
2203
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
2204
        (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
2205
        /* jump to same page: we can use a direct jump */
2206
        tcg_gen_goto_tb(tb_num);
2207
        gen_jmp_im(eip);
2208
        tcg_gen_exit_tb((long)tb + tb_num);
2209
    } else {
2210
        /* jump to another page: currently not optimized */
2211
        gen_jmp_im(eip);
2212
        gen_eob(s);
2213
    }
2214
}
2215

    
2216
static inline void gen_jcc(DisasContext *s, int b,
2217
                           target_ulong val, target_ulong next_eip)
2218
{
2219
    int l1, l2, cc_op;
2220

    
2221
    cc_op = s->cc_op;
2222
    if (s->cc_op != CC_OP_DYNAMIC) {
2223
        gen_op_set_cc_op(s->cc_op);
2224
        s->cc_op = CC_OP_DYNAMIC;
2225
    }
2226
    if (s->jmp_opt) {
2227
        l1 = gen_new_label();
2228
        gen_jcc1(s, cc_op, b, l1);
2229
        
2230
        gen_goto_tb(s, 0, next_eip);
2231

    
2232
        gen_set_label(l1);
2233
        gen_goto_tb(s, 1, val);
2234
        s->is_jmp = 3;
2235
    } else {
2236

    
2237
        l1 = gen_new_label();
2238
        l2 = gen_new_label();
2239
        gen_jcc1(s, cc_op, b, l1);
2240

    
2241
        gen_jmp_im(next_eip);
2242
        tcg_gen_br(l2);
2243

    
2244
        gen_set_label(l1);
2245
        gen_jmp_im(val);
2246
        gen_set_label(l2);
2247
        gen_eob(s);
2248
    }
2249
}
2250

    
2251
static void gen_setcc(DisasContext *s, int b)
2252
{
2253
    int inv, jcc_op, l1;
2254
    TCGv t0;
2255

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

    
2280
static inline void gen_op_movl_T0_seg(int seg_reg)
2281
{
2282
    tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
2283
                     offsetof(CPUX86State,segs[seg_reg].selector));
2284
}
2285

    
2286
static inline void gen_op_movl_seg_T0_vm(int seg_reg)
2287
{
2288
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
2289
    tcg_gen_st32_tl(cpu_T[0], cpu_env, 
2290
                    offsetof(CPUX86State,segs[seg_reg].selector));
2291
    tcg_gen_shli_tl(cpu_T[0], cpu_T[0], 4);
2292
    tcg_gen_st_tl(cpu_T[0], cpu_env, 
2293
                  offsetof(CPUX86State,segs[seg_reg].base));
2294
}
2295

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

    
2320
static inline int svm_is_rep(int prefixes)
2321
{
2322
    return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
2323
}
2324

    
2325
static inline int
2326
gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2327
                              uint32_t type, uint64_t param)
2328
{
2329
    if(!(s->flags & (INTERCEPT_SVM_MASK)))
2330
        /* no SVM activated */
2331
        return 0;
2332
    switch(type) {
2333
        /* CRx and DRx reads/writes */
2334
        case SVM_EXIT_READ_CR0 ... SVM_EXIT_EXCP_BASE - 1:
2335
            if (s->cc_op != CC_OP_DYNAMIC) {
2336
                gen_op_set_cc_op(s->cc_op);
2337
            }
2338
            gen_jmp_im(pc_start - s->cs_base);
2339
            tcg_gen_helper_0_2(helper_svm_check_intercept_param, 
2340
                               tcg_const_i32(type), tcg_const_i64(param));
2341
            /* this is a special case as we do not know if the interception occurs
2342
               so we assume there was none */
2343
            return 0;
2344
        case SVM_EXIT_MSR:
2345
            if(s->flags & (1ULL << INTERCEPT_MSR_PROT)) {
2346
                if (s->cc_op != CC_OP_DYNAMIC) {
2347
                    gen_op_set_cc_op(s->cc_op);
2348
                }
2349
                gen_jmp_im(pc_start - s->cs_base);
2350
                tcg_gen_helper_0_2(helper_svm_check_intercept_param,
2351
                                   tcg_const_i32(type), tcg_const_i64(param));
2352
                /* this is a special case as we do not know if the interception occurs
2353
                   so we assume there was none */
2354
                return 0;
2355
            }
2356
            break;
2357
        default:
2358
            if(s->flags & (1ULL << ((type - SVM_EXIT_INTR) + INTERCEPT_INTR))) {
2359
                if (s->cc_op != CC_OP_DYNAMIC) {
2360
                    gen_op_set_cc_op(s->cc_op);
2361
                }
2362
                gen_jmp_im(pc_start - s->cs_base);
2363
                tcg_gen_helper_0_2(helper_vmexit,
2364
                                   tcg_const_i32(type), tcg_const_i64(param));
2365
                /* we can optimize this one so TBs don't get longer
2366
                   than up to vmexit */
2367
                gen_eob(s);
2368
                return 1;
2369
            }
2370
    }
2371
    return 0;
2372
}
2373

    
2374
static inline int
2375
gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
2376
{
2377
    return gen_svm_check_intercept_param(s, pc_start, type, 0);
2378
}
2379

    
2380
static inline void gen_stack_update(DisasContext *s, int addend)
2381
{
2382
#ifdef TARGET_X86_64
2383
    if (CODE64(s)) {
2384
        gen_op_add_reg_im(2, R_ESP, addend);
2385
    } else
2386
#endif
2387
    if (s->ss32) {
2388
        gen_op_add_reg_im(1, R_ESP, addend);
2389
    } else {
2390
        gen_op_add_reg_im(0, R_ESP, addend);
2391
    }
2392
}
2393

    
2394
/* generate a push. It depends on ss32, addseg and dflag */
2395
static void gen_push_T0(DisasContext *s)
2396
{
2397
#ifdef TARGET_X86_64
2398
    if (CODE64(s)) {
2399
        gen_op_movq_A0_reg(R_ESP);
2400
        if (s->dflag) {
2401
            gen_op_addq_A0_im(-8);
2402
            gen_op_st_T0_A0(OT_QUAD + s->mem_index);
2403
        } else {
2404
            gen_op_addq_A0_im(-2);
2405
            gen_op_st_T0_A0(OT_WORD + s->mem_index);
2406
        }
2407
        gen_op_mov_reg_A0(2, R_ESP);
2408
    } else
2409
#endif
2410
    {
2411
        gen_op_movl_A0_reg(R_ESP);
2412
        if (!s->dflag)
2413
            gen_op_addl_A0_im(-2);
2414
        else
2415
            gen_op_addl_A0_im(-4);
2416
        if (s->ss32) {
2417
            if (s->addseg) {
2418
                tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2419
                gen_op_addl_A0_seg(R_SS);
2420
            }
2421
        } else {
2422
            gen_op_andl_A0_ffff();
2423
            tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2424
            gen_op_addl_A0_seg(R_SS);
2425
        }
2426
        gen_op_st_T0_A0(s->dflag + 1 + s->mem_index);
2427
        if (s->ss32 && !s->addseg)
2428
            gen_op_mov_reg_A0(1, R_ESP);
2429
        else
2430
            gen_op_mov_reg_T1(s->ss32 + 1, R_ESP);
2431
    }
2432
}
2433

    
2434
/* generate a push. It depends on ss32, addseg and dflag */
2435
/* slower version for T1, only used for call Ev */
2436
static void gen_push_T1(DisasContext *s)
2437
{
2438
#ifdef TARGET_X86_64
2439
    if (CODE64(s)) {
2440
        gen_op_movq_A0_reg(R_ESP);
2441
        if (s->dflag) {
2442
            gen_op_addq_A0_im(-8);
2443
            gen_op_st_T1_A0(OT_QUAD + s->mem_index);
2444
        } else {
2445
            gen_op_addq_A0_im(-2);
2446
            gen_op_st_T0_A0(OT_WORD + s->mem_index);
2447
        }
2448
        gen_op_mov_reg_A0(2, R_ESP);
2449
    } else
2450
#endif
2451
    {
2452
        gen_op_movl_A0_reg(R_ESP);
2453
        if (!s->dflag)
2454
            gen_op_addl_A0_im(-2);
2455
        else
2456
            gen_op_addl_A0_im(-4);
2457
        if (s->ss32) {
2458
            if (s->addseg) {
2459
                gen_op_addl_A0_seg(R_SS);
2460
            }
2461
        } else {
2462
            gen_op_andl_A0_ffff();
2463
            gen_op_addl_A0_seg(R_SS);
2464
        }
2465
        gen_op_st_T1_A0(s->dflag + 1 + s->mem_index);
2466

    
2467
        if (s->ss32 && !s->addseg)
2468
            gen_op_mov_reg_A0(1, R_ESP);
2469
        else
2470
            gen_stack_update(s, (-2) << s->dflag);
2471
    }
2472
}
2473

    
2474
/* two step pop is necessary for precise exceptions */
2475
static void gen_pop_T0(DisasContext *s)
2476
{
2477
#ifdef TARGET_X86_64
2478
    if (CODE64(s)) {
2479
        gen_op_movq_A0_reg(R_ESP);
2480
        gen_op_ld_T0_A0((s->dflag ? OT_QUAD : OT_WORD) + s->mem_index);
2481
    } else
2482
#endif
2483
    {
2484
        gen_op_movl_A0_reg(R_ESP);
2485
        if (s->ss32) {
2486
            if (s->addseg)
2487
                gen_op_addl_A0_seg(R_SS);
2488
        } else {
2489
            gen_op_andl_A0_ffff();
2490
            gen_op_addl_A0_seg(R_SS);
2491
        }
2492
        gen_op_ld_T0_A0(s->dflag + 1 + s->mem_index);
2493
    }
2494
}
2495

    
2496
static void gen_pop_update(DisasContext *s)
2497
{
2498
#ifdef TARGET_X86_64
2499
    if (CODE64(s) && s->dflag) {
2500
        gen_stack_update(s, 8);
2501
    } else
2502
#endif
2503
    {
2504
        gen_stack_update(s, 2 << s->dflag);
2505
    }
2506
}
2507

    
2508
static void gen_stack_A0(DisasContext *s)
2509
{
2510
    gen_op_movl_A0_reg(R_ESP);
2511
    if (!s->ss32)
2512
        gen_op_andl_A0_ffff();
2513
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2514
    if (s->addseg)
2515
        gen_op_addl_A0_seg(R_SS);
2516
}
2517

    
2518
/* NOTE: wrap around in 16 bit not fully handled */
2519
static void gen_pusha(DisasContext *s)
2520
{
2521
    int i;
2522
    gen_op_movl_A0_reg(R_ESP);
2523
    gen_op_addl_A0_im(-16 <<  s->dflag);
2524
    if (!s->ss32)
2525
        gen_op_andl_A0_ffff();
2526
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2527
    if (s->addseg)
2528
        gen_op_addl_A0_seg(R_SS);
2529
    for(i = 0;i < 8; i++) {
2530
        gen_op_mov_TN_reg(OT_LONG, 0, 7 - i);
2531
        gen_op_st_T0_A0(OT_WORD + s->dflag + s->mem_index);
2532
        gen_op_addl_A0_im(2 <<  s->dflag);
2533
    }
2534
    gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2535
}
2536

    
2537
/* NOTE: wrap around in 16 bit not fully handled */
2538
static void gen_popa(DisasContext *s)
2539
{
2540
    int i;
2541
    gen_op_movl_A0_reg(R_ESP);
2542
    if (!s->ss32)
2543
        gen_op_andl_A0_ffff();
2544
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2545
    tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 16 <<  s->dflag);
2546
    if (s->addseg)
2547
        gen_op_addl_A0_seg(R_SS);
2548
    for(i = 0;i < 8; i++) {
2549
        /* ESP is not reloaded */
2550
        if (i != 3) {
2551
            gen_op_ld_T0_A0(OT_WORD + s->dflag + s->mem_index);
2552
            gen_op_mov_reg_T0(OT_WORD + s->dflag, 7 - i);
2553
        }
2554
        gen_op_addl_A0_im(2 <<  s->dflag);
2555
    }
2556
    gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2557
}
2558

    
2559
static void gen_enter(DisasContext *s, int esp_addend, int level)
2560
{
2561
    int ot, opsize;
2562

    
2563
    level &= 0x1f;
2564
#ifdef TARGET_X86_64
2565
    if (CODE64(s)) {
2566
        ot = s->dflag ? OT_QUAD : OT_WORD;
2567
        opsize = 1 << ot;
2568

    
2569
        gen_op_movl_A0_reg(R_ESP);
2570
        gen_op_addq_A0_im(-opsize);
2571
        tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2572

    
2573
        /* push bp */
2574
        gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
2575
        gen_op_st_T0_A0(ot + s->mem_index);
2576
        if (level) {
2577
            /* XXX: must save state */
2578
            tcg_gen_helper_0_3(helper_enter64_level,
2579
                               tcg_const_i32(level),
2580
                               tcg_const_i32((ot == OT_QUAD)),
2581
                               cpu_T[1]);
2582
        }
2583
        gen_op_mov_reg_T1(ot, R_EBP);
2584
        tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2585
        gen_op_mov_reg_T1(OT_QUAD, R_ESP);
2586
    } else
2587
#endif
2588
    {
2589
        ot = s->dflag + OT_WORD;
2590
        opsize = 2 << s->dflag;
2591

    
2592
        gen_op_movl_A0_reg(R_ESP);
2593
        gen_op_addl_A0_im(-opsize);
2594
        if (!s->ss32)
2595
            gen_op_andl_A0_ffff();
2596
        tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2597
        if (s->addseg)
2598
            gen_op_addl_A0_seg(R_SS);
2599
        /* push bp */
2600
        gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
2601
        gen_op_st_T0_A0(ot + s->mem_index);
2602
        if (level) {
2603
            /* XXX: must save state */
2604
            tcg_gen_helper_0_3(helper_enter_level,
2605
                               tcg_const_i32(level),
2606
                               tcg_const_i32(s->dflag),
2607
                               cpu_T[1]);
2608
        }
2609
        gen_op_mov_reg_T1(ot, R_EBP);
2610
        tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2611
        gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2612
    }
2613
}
2614

    
2615
static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2616
{
2617
    if (s->cc_op != CC_OP_DYNAMIC)
2618
        gen_op_set_cc_op(s->cc_op);
2619
    gen_jmp_im(cur_eip);
2620
    tcg_gen_helper_0_1(helper_raise_exception, tcg_const_i32(trapno));
2621
    s->is_jmp = 3;
2622
}
2623

    
2624
/* an interrupt is different from an exception because of the
2625
   privilege checks */
2626
static void gen_interrupt(DisasContext *s, int intno,
2627
                          target_ulong cur_eip, target_ulong next_eip)
2628
{
2629
    if (s->cc_op != CC_OP_DYNAMIC)
2630
        gen_op_set_cc_op(s->cc_op);
2631
    gen_jmp_im(cur_eip);
2632
    tcg_gen_helper_0_2(helper_raise_interrupt, 
2633
                       tcg_const_i32(intno), 
2634
                       tcg_const_i32(next_eip - cur_eip));
2635
    s->is_jmp = 3;
2636
}
2637

    
2638
static void gen_debug(DisasContext *s, target_ulong cur_eip)
2639
{
2640
    if (s->cc_op != CC_OP_DYNAMIC)
2641
        gen_op_set_cc_op(s->cc_op);
2642
    gen_jmp_im(cur_eip);
2643
    tcg_gen_helper_0_0(helper_debug);
2644
    s->is_jmp = 3;
2645
}
2646

    
2647
/* generate a generic end of block. Trace exception is also generated
2648
   if needed */
2649
static void gen_eob(DisasContext *s)
2650
{
2651
    if (s->cc_op != CC_OP_DYNAMIC)
2652
        gen_op_set_cc_op(s->cc_op);
2653
    if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
2654
        tcg_gen_helper_0_0(helper_reset_inhibit_irq);
2655
    }
2656
    if (s->singlestep_enabled) {
2657
        tcg_gen_helper_0_0(helper_debug);
2658
    } else if (s->tf) {
2659
        tcg_gen_helper_0_0(helper_single_step);
2660
    } else {
2661
        tcg_gen_exit_tb(0);
2662
    }
2663
    s->is_jmp = 3;
2664
}
2665

    
2666
/* generate a jump to eip. No segment change must happen before as a
2667
   direct call to the next block may occur */
2668
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2669
{
2670
    if (s->jmp_opt) {
2671
        if (s->cc_op != CC_OP_DYNAMIC) {
2672
            gen_op_set_cc_op(s->cc_op);
2673
            s->cc_op = CC_OP_DYNAMIC;
2674
        }
2675
        gen_goto_tb(s, tb_num, eip);
2676
        s->is_jmp = 3;
2677
    } else {
2678
        gen_jmp_im(eip);
2679
        gen_eob(s);
2680
    }
2681
}
2682

    
2683
static void gen_jmp(DisasContext *s, target_ulong eip)
2684
{
2685
    gen_jmp_tb(s, eip, 0);
2686
}
2687

    
2688
static inline void gen_ldq_env_A0(int idx, int offset)
2689
{
2690
    int mem_index = (idx >> 2) - 1;
2691
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2692
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
2693
}
2694

    
2695
static inline void gen_stq_env_A0(int idx, int offset)
2696
{
2697
    int mem_index = (idx >> 2) - 1;
2698
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
2699
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2700
}
2701

    
2702
static inline void gen_ldo_env_A0(int idx, int offset)
2703
{
2704
    int mem_index = (idx >> 2) - 1;
2705
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2706
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2707
    tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2708
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2709
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2710
}
2711

    
2712
static inline void gen_sto_env_A0(int idx, int offset)
2713
{
2714
    int mem_index = (idx >> 2) - 1;
2715
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2716
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2717
    tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2718
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2719
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2720
}
2721

    
2722
static inline void gen_op_movo(int d_offset, int s_offset)
2723
{
2724
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2725
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2726
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + 8);
2727
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + 8);
2728
}
2729

    
2730
static inline void gen_op_movq(int d_offset, int s_offset)
2731
{
2732
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2733
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2734
}
2735

    
2736
static inline void gen_op_movl(int d_offset, int s_offset)
2737
{
2738
    tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
2739
    tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
2740
}
2741

    
2742
static inline void gen_op_movq_env_0(int d_offset)
2743
{
2744
    tcg_gen_movi_i64(cpu_tmp1_i64, 0);
2745
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2746
}
2747

    
2748
#define SSE_SPECIAL ((void *)1)
2749
#define SSE_DUMMY ((void *)2)
2750

    
2751
#define MMX_OP2(x) { helper_ ## x ## _mmx, helper_ ## x ## _xmm }
2752
#define SSE_FOP(x) { helper_ ## x ## ps, helper_ ## x ## pd, \
2753
                     helper_ ## x ## ss, helper_ ## x ## sd, }
2754

    
2755
static void *sse_op_table1[256][4] = {
2756
    /* 3DNow! extensions */
2757
    [0x0e] = { SSE_DUMMY }, /* femms */
2758
    [0x0f] = { SSE_DUMMY }, /* pf... */
2759
    /* pure SSE operations */
2760
    [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2761
    [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2762
    [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2763
    [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
2764
    [0x14] = { helper_punpckldq_xmm, helper_punpcklqdq_xmm },
2765
    [0x15] = { helper_punpckhdq_xmm, helper_punpckhqdq_xmm },
2766
    [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */
2767
    [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */
2768

    
2769
    [0x28] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2770
    [0x29] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2771
    [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2772
    [0x2b] = { SSE_SPECIAL, SSE_SPECIAL },  /* movntps, movntpd */
2773
    [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2774
    [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2775
    [0x2e] = { helper_ucomiss, helper_ucomisd },
2776
    [0x2f] = { helper_comiss, helper_comisd },
2777
    [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2778
    [0x51] = SSE_FOP(sqrt),
2779
    [0x52] = { helper_rsqrtps, NULL, helper_rsqrtss, NULL },
2780
    [0x53] = { helper_rcpps, NULL, helper_rcpss, NULL },
2781
    [0x54] = { helper_pand_xmm, helper_pand_xmm }, /* andps, andpd */
2782
    [0x55] = { helper_pandn_xmm, helper_pandn_xmm }, /* andnps, andnpd */
2783
    [0x56] = { helper_por_xmm, helper_por_xmm }, /* orps, orpd */
2784
    [0x57] = { helper_pxor_xmm, helper_pxor_xmm }, /* xorps, xorpd */
2785
    [0x58] = SSE_FOP(add),
2786
    [0x59] = SSE_FOP(mul),
2787
    [0x5a] = { helper_cvtps2pd, helper_cvtpd2ps,
2788
               helper_cvtss2sd, helper_cvtsd2ss },
2789
    [0x5b] = { helper_cvtdq2ps, helper_cvtps2dq, helper_cvttps2dq },
2790
    [0x5c] = SSE_FOP(sub),
2791
    [0x5d] = SSE_FOP(min),
2792
    [0x5e] = SSE_FOP(div),
2793
    [0x5f] = SSE_FOP(max),
2794

    
2795
    [0xc2] = SSE_FOP(cmpeq),
2796
    [0xc6] = { helper_shufps, helper_shufpd },
2797

    
2798
    /* MMX ops and their SSE extensions */
2799
    [0x60] = MMX_OP2(punpcklbw),
2800
    [0x61] = MMX_OP2(punpcklwd),
2801
    [0x62] = MMX_OP2(punpckldq),
2802
    [0x63] = MMX_OP2(packsswb),
2803
    [0x64] = MMX_OP2(pcmpgtb),
2804
    [0x65] = MMX_OP2(pcmpgtw),
2805
    [0x66] = MMX_OP2(pcmpgtl),
2806
    [0x67] = MMX_OP2(packuswb),
2807
    [0x68] = MMX_OP2(punpckhbw),
2808
    [0x69] = MMX_OP2(punpckhwd),
2809
    [0x6a] = MMX_OP2(punpckhdq),
2810
    [0x6b] = MMX_OP2(packssdw),
2811
    [0x6c] = { NULL, helper_punpcklqdq_xmm },
2812
    [0x6d] = { NULL, helper_punpckhqdq_xmm },
2813
    [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
2814
    [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
2815
    [0x70] = { helper_pshufw_mmx,
2816
               helper_pshufd_xmm,
2817
               helper_pshufhw_xmm,
2818
               helper_pshuflw_xmm },
2819
    [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
2820
    [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
2821
    [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
2822
    [0x74] = MMX_OP2(pcmpeqb),
2823
    [0x75] = MMX_OP2(pcmpeqw),
2824
    [0x76] = MMX_OP2(pcmpeql),
2825
    [0x77] = { SSE_DUMMY }, /* emms */
2826
    [0x7c] = { NULL, helper_haddpd, NULL, helper_haddps },
2827
    [0x7d] = { NULL, helper_hsubpd, NULL, helper_hsubps },
2828
    [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
2829
    [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
2830
    [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
2831
    [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
2832
    [0xd0] = { NULL, helper_addsubpd, NULL, helper_addsubps },
2833
    [0xd1] = MMX_OP2(psrlw),
2834
    [0xd2] = MMX_OP2(psrld),
2835
    [0xd3] = MMX_OP2(psrlq),
2836
    [0xd4] = MMX_OP2(paddq),
2837
    [0xd5] = MMX_OP2(pmullw),
2838
    [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2839
    [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
2840
    [0xd8] = MMX_OP2(psubusb),
2841
    [0xd9] = MMX_OP2(psubusw),
2842
    [0xda] = MMX_OP2(pminub),
2843
    [0xdb] = MMX_OP2(pand),
2844
    [0xdc] = MMX_OP2(paddusb),
2845
    [0xdd] = MMX_OP2(paddusw),
2846
    [0xde] = MMX_OP2(pmaxub),
2847
    [0xdf] = MMX_OP2(pandn),
2848
    [0xe0] = MMX_OP2(pavgb),
2849
    [0xe1] = MMX_OP2(psraw),
2850
    [0xe2] = MMX_OP2(psrad),
2851
    [0xe3] = MMX_OP2(pavgw),
2852
    [0xe4] = MMX_OP2(pmulhuw),
2853
    [0xe5] = MMX_OP2(pmulhw),
2854
    [0xe6] = { NULL, helper_cvttpd2dq, helper_cvtdq2pd, helper_cvtpd2dq },
2855
    [0xe7] = { SSE_SPECIAL , SSE_SPECIAL },  /* movntq, movntq */
2856
    [0xe8] = MMX_OP2(psubsb),
2857
    [0xe9] = MMX_OP2(psubsw),
2858
    [0xea] = MMX_OP2(pminsw),
2859
    [0xeb] = MMX_OP2(por),
2860
    [0xec] = MMX_OP2(paddsb),
2861
    [0xed] = MMX_OP2(paddsw),
2862
    [0xee] = MMX_OP2(pmaxsw),
2863
    [0xef] = MMX_OP2(pxor),
2864
    [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
2865
    [0xf1] = MMX_OP2(psllw),
2866
    [0xf2] = MMX_OP2(pslld),
2867
    [0xf3] = MMX_OP2(psllq),
2868
    [0xf4] = MMX_OP2(pmuludq),
2869
    [0xf5] = MMX_OP2(pmaddwd),
2870
    [0xf6] = MMX_OP2(psadbw),
2871
    [0xf7] = MMX_OP2(maskmov),
2872
    [0xf8] = MMX_OP2(psubb),
2873
    [0xf9] = MMX_OP2(psubw),
2874
    [0xfa] = MMX_OP2(psubl),
2875
    [0xfb] = MMX_OP2(psubq),
2876
    [0xfc] = MMX_OP2(paddb),
2877
    [0xfd] = MMX_OP2(paddw),
2878
    [0xfe] = MMX_OP2(paddl),
2879
};
2880

    
2881
static void *sse_op_table2[3 * 8][2] = {
2882
    [0 + 2] = MMX_OP2(psrlw),
2883
    [0 + 4] = MMX_OP2(psraw),
2884
    [0 + 6] = MMX_OP2(psllw),
2885
    [8 + 2] = MMX_OP2(psrld),
2886
    [8 + 4] = MMX_OP2(psrad),
2887
    [8 + 6] = MMX_OP2(pslld),
2888
    [16 + 2] = MMX_OP2(psrlq),
2889
    [16 + 3] = { NULL, helper_psrldq_xmm },
2890
    [16 + 6] = MMX_OP2(psllq),
2891
    [16 + 7] = { NULL, helper_pslldq_xmm },
2892
};
2893

    
2894
static void *sse_op_table3[4 * 3] = {
2895
    helper_cvtsi2ss,
2896
    helper_cvtsi2sd,
2897
    X86_64_ONLY(helper_cvtsq2ss),
2898
    X86_64_ONLY(helper_cvtsq2sd),
2899

    
2900
    helper_cvttss2si,
2901
    helper_cvttsd2si,
2902
    X86_64_ONLY(helper_cvttss2sq),
2903
    X86_64_ONLY(helper_cvttsd2sq),
2904

    
2905
    helper_cvtss2si,
2906
    helper_cvtsd2si,
2907
    X86_64_ONLY(helper_cvtss2sq),
2908
    X86_64_ONLY(helper_cvtsd2sq),
2909
};
2910

    
2911
static void *sse_op_table4[8][4] = {
2912
    SSE_FOP(cmpeq),
2913
    SSE_FOP(cmplt),
2914
    SSE_FOP(cmple),
2915
    SSE_FOP(cmpunord),
2916
    SSE_FOP(cmpneq),
2917
    SSE_FOP(cmpnlt),
2918
    SSE_FOP(cmpnle),
2919
    SSE_FOP(cmpord),
2920
};
2921

    
2922
static void *sse_op_table5[256] = {
2923
    [0x0c] = helper_pi2fw,
2924
    [0x0d] = helper_pi2fd,
2925
    [0x1c] = helper_pf2iw,
2926
    [0x1d] = helper_pf2id,
2927
    [0x8a] = helper_pfnacc,
2928
    [0x8e] = helper_pfpnacc,
2929
    [0x90] = helper_pfcmpge,
2930
    [0x94] = helper_pfmin,
2931
    [0x96] = helper_pfrcp,
2932
    [0x97] = helper_pfrsqrt,
2933
    [0x9a] = helper_pfsub,
2934
    [0x9e] = helper_pfadd,
2935
    [0xa0] = helper_pfcmpgt,
2936
    [0xa4] = helper_pfmax,
2937
    [0xa6] = helper_movq, /* pfrcpit1; no need to actually increase precision */
2938
    [0xa7] = helper_movq, /* pfrsqit1 */
2939
    [0xaa] = helper_pfsubr,
2940
    [0xae] = helper_pfacc,
2941
    [0xb0] = helper_pfcmpeq,
2942
    [0xb4] = helper_pfmul,
2943
    [0xb6] = helper_movq, /* pfrcpit2 */
2944
    [0xb7] = helper_pmulhrw_mmx,
2945
    [0xbb] = helper_pswapd,
2946
    [0xbf] = helper_pavgb_mmx /* pavgusb */
2947
};
2948

    
2949
static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
2950
{
2951
    int b1, op1_offset, op2_offset, is_xmm, val, ot;
2952
    int modrm, mod, rm, reg, reg_addr, offset_addr;
2953
    void *sse_op2;
2954

    
2955
    b &= 0xff;
2956
    if (s->prefix & PREFIX_DATA)
2957
        b1 = 1;
2958
    else if (s->prefix & PREFIX_REPZ)
2959
        b1 = 2;
2960
    else if (s->prefix & PREFIX_REPNZ)
2961
        b1 = 3;
2962
    else
2963
        b1 = 0;
2964
    sse_op2 = sse_op_table1[b][b1];
2965
    if (!sse_op2)
2966
        goto illegal_op;
2967
    if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
2968
        is_xmm = 1;
2969
    } else {
2970
        if (b1 == 0) {
2971
            /* MMX case */
2972
            is_xmm = 0;
2973
        } else {
2974
            is_xmm = 1;
2975
        }
2976
    }
2977
    /* simple MMX/SSE operation */
2978
    if (s->flags & HF_TS_MASK) {
2979
        gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
2980
        return;
2981
    }
2982
    if (s->flags & HF_EM_MASK) {
2983
    illegal_op:
2984
        gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
2985
        return;
2986
    }
2987
    if (is_xmm && !(s->flags & HF_OSFXSR_MASK))
2988
        goto illegal_op;
2989
    if (b == 0x0e) {
2990
        if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
2991
            goto illegal_op;
2992
        /* femms */
2993
        tcg_gen_helper_0_0(helper_emms);
2994
        return;
2995
    }
2996
    if (b == 0x77) {
2997
        /* emms */
2998
        tcg_gen_helper_0_0(helper_emms);
2999
        return;
3000
    }
3001
    /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3002
       the static cpu state) */
3003
    if (!is_xmm) {
3004
        tcg_gen_helper_0_0(helper_enter_mmx);
3005
    }
3006

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

    
3599
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3600
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3601
            tcg_gen_helper_0_3(sse_op2, cpu_ptr0, cpu_ptr1, cpu_A0);
3602
            break;
3603
        default:
3604
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3605
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3606
            tcg_gen_helper_0_2(sse_op2, cpu_ptr0, cpu_ptr1);
3607
            break;
3608
        }
3609
        if (b == 0x2e || b == 0x2f) {
3610
            s->cc_op = CC_OP_EFLAGS;
3611
        }
3612
    }
3613
}
3614

    
3615
/* convert one instruction. s->is_jmp is set if the translation must
3616
   be stopped. Return the next pc value */
3617
static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
3618
{
3619
    int b, prefixes, aflag, dflag;
3620
    int shift, ot;
3621
    int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
3622
    target_ulong next_eip, tval;
3623
    int rex_w, rex_r;
3624

    
3625
    if (unlikely(loglevel & CPU_LOG_TB_OP))
3626
        tcg_gen_debug_insn_start(pc_start);
3627
    s->pc = pc_start;
3628
    prefixes = 0;
3629
    aflag = s->code32;
3630
    dflag = s->code32;
3631
    s->override = -1;
3632
    rex_w = -1;
3633
    rex_r = 0;
3634
#ifdef TARGET_X86_64
3635
    s->rex_x = 0;
3636
    s->rex_b = 0;
3637
    x86_64_hregs = 0;
3638
#endif
3639
    s->rip_offset = 0; /* for relative ip address */
3640
 next_byte:
3641
    b = ldub_code(s->pc);
3642
    s->pc++;
3643
    /* check prefixes */
3644
#ifdef TARGET_X86_64
3645
    if (CODE64(s)) {
3646
        switch (b) {
3647
        case 0xf3:
3648
            prefixes |= PREFIX_REPZ;
3649
            goto next_byte;
3650
        case 0xf2:
3651
            prefixes |= PREFIX_REPNZ;
3652
            goto next_byte;
3653
        case 0xf0:
3654
            prefixes |= PREFIX_LOCK;
3655
            goto next_byte;
3656
        case 0x2e:
3657
            s->override = R_CS;
3658
            goto next_byte;
3659
        case 0x36:
3660
            s->override = R_SS;
3661
            goto next_byte;
3662
        case 0x3e:
3663
            s->override = R_DS;
3664
            goto next_byte;
3665
        case 0x26:
3666
            s->override = R_ES;
3667
            goto next_byte;
3668
        case 0x64:
3669
            s->override = R_FS;
3670
            goto next_byte;
3671
        case 0x65:
3672
            s->override = R_GS;
3673
            goto next_byte;
3674
        case 0x66:
3675
            prefixes |= PREFIX_DATA;
3676
            goto next_byte;
3677
        case 0x67:
3678
            prefixes |= PREFIX_ADR;
3679
            goto next_byte;
3680
        case 0x40 ... 0x4f:
3681
            /* REX prefix */
3682
            rex_w = (b >> 3) & 1;
3683
            rex_r = (b & 0x4) << 1;
3684
            s->rex_x = (b & 0x2) << 2;
3685
            REX_B(s) = (b & 0x1) << 3;
3686
            x86_64_hregs = 1; /* select uniform byte register addressing */
3687
            goto next_byte;
3688
        }
3689
        if (rex_w == 1) {
3690
            /* 0x66 is ignored if rex.w is set */
3691
            dflag = 2;
3692
        } else {
3693
            if (prefixes & PREFIX_DATA)
3694
                dflag ^= 1;
3695
        }
3696
        if (!(prefixes & PREFIX_ADR))
3697
            aflag = 2;
3698
    } else
3699
#endif
3700
    {
3701
        switch (b) {
3702
        case 0xf3:
3703
            prefixes |= PREFIX_REPZ;
3704
            goto next_byte;
3705
        case 0xf2:
3706
            prefixes |= PREFIX_REPNZ;
3707
            goto next_byte;
3708
        case 0xf0:
3709
            prefixes |= PREFIX_LOCK;
3710
            goto next_byte;
3711
        case 0x2e:
3712
            s->override = R_CS;
3713
            goto next_byte;
3714
        case 0x36:
3715
            s->override = R_SS;
3716
            goto next_byte;
3717
        case 0x3e:
3718
            s->override = R_DS;
3719
            goto next_byte;
3720
        case 0x26:
3721
            s->override = R_ES;
3722
            goto next_byte;
3723
        case 0x64:
3724
            s->override = R_FS;
3725
            goto next_byte;
3726
        case 0x65:
3727
            s->override = R_GS;
3728
            goto next_byte;
3729
        case 0x66:
3730
            prefixes |= PREFIX_DATA;
3731
            goto next_byte;
3732
        case 0x67:
3733
            prefixes |= PREFIX_ADR;
3734
            goto next_byte;
3735
        }
3736
        if (prefixes & PREFIX_DATA)
3737
            dflag ^= 1;
3738
        if (prefixes & PREFIX_ADR)
3739
            aflag ^= 1;
3740
    }
3741

    
3742
    s->prefix = prefixes;
3743
    s->aflag = aflag;
3744
    s->dflag = dflag;
3745

    
3746
    /* lock generation */
3747
    if (prefixes & PREFIX_LOCK)
3748
        tcg_gen_helper_0_0(helper_lock);
3749

    
3750
    /* now check op code */
3751
 reswitch:
3752
    switch(b) {
3753
    case 0x0f:
3754
        /**************************/
3755
        /* extended op code */
3756
        b = ldub_code(s->pc++) | 0x100;
3757
        goto reswitch;
3758

    
3759
        /**************************/
3760
        /* arith & logic */
3761
    case 0x00 ... 0x05:
3762
    case 0x08 ... 0x0d:
3763
    case 0x10 ... 0x15:
3764
    case 0x18 ... 0x1d:
3765
    case 0x20 ... 0x25:
3766
    case 0x28 ... 0x2d:
3767
    case 0x30 ... 0x35:
3768
    case 0x38 ... 0x3d:
3769
        {
3770
            int op, f, val;
3771
            op = (b >> 3) & 7;
3772
            f = (b >> 1) & 3;
3773

    
3774
            if ((b & 1) == 0)
3775
                ot = OT_BYTE;
3776
            else
3777
                ot = dflag + OT_WORD;
3778

    
3779
            switch(f) {
3780
            case 0: /* OP Ev, Gv */
3781
                modrm = ldub_code(s->pc++);
3782
                reg = ((modrm >> 3) & 7) | rex_r;
3783
                mod = (modrm >> 6) & 3;
3784
                rm = (modrm & 7) | REX_B(s);
3785
                if (mod != 3) {
3786
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3787
                    opreg = OR_TMP0;
3788
                } else if (op == OP_XORL && rm == reg) {
3789
                xor_zero:
3790
                    /* xor reg, reg optimisation */
3791
                    gen_op_movl_T0_0();
3792
                    s->cc_op = CC_OP_LOGICB + ot;
3793
                    gen_op_mov_reg_T0(ot, reg);
3794
                    gen_op_update1_cc();
3795
                    break;
3796
                } else {
3797
                    opreg = rm;
3798
                }
3799
                gen_op_mov_TN_reg(ot, 1, reg);
3800
                gen_op(s, op, ot, opreg);
3801
                break;
3802
            case 1: /* OP Gv, Ev */
3803
                modrm = ldub_code(s->pc++);
3804
                mod = (modrm >> 6) & 3;
3805
                reg = ((modrm >> 3) & 7) | rex_r;
3806
                rm = (modrm & 7) | REX_B(s);
3807
                if (mod != 3) {
3808
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3809
                    gen_op_ld_T1_A0(ot + s->mem_index);
3810
                } else if (op == OP_XORL && rm == reg) {
3811
                    goto xor_zero;
3812
                } else {
3813
                    gen_op_mov_TN_reg(ot, 1, rm);
3814
                }
3815
                gen_op(s, op, ot, reg);
3816
                break;
3817
            case 2: /* OP A, Iv */
3818
                val = insn_get(s, ot);
3819
                gen_op_movl_T1_im(val);
3820
                gen_op(s, op, ot, OR_EAX);
3821
                break;
3822
            }
3823
        }
3824
        break;
3825

    
3826
    case 0x80: /* GRP1 */
3827
    case 0x81:
3828
    case 0x82:
3829
    case 0x83:
3830
        {
3831
            int val;
3832

    
3833
            if ((b & 1) == 0)
3834
                ot = OT_BYTE;
3835
            else
3836
                ot = dflag + OT_WORD;
3837

    
3838
            modrm = ldub_code(s->pc++);
3839
            mod = (modrm >> 6) & 3;
3840
            rm = (modrm & 7) | REX_B(s);
3841
            op = (modrm >> 3) & 7;
3842

    
3843
            if (mod != 3) {
3844
                if (b == 0x83)
3845
                    s->rip_offset = 1;
3846
                else
3847
                    s->rip_offset = insn_const_size(ot);
3848
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3849
                opreg = OR_TMP0;
3850
            } else {
3851
                opreg = rm;
3852
            }
3853

    
3854
            switch(b) {
3855
            default:
3856
            case 0x80:
3857
            case 0x81:
3858
            case 0x82:
3859
                val = insn_get(s, ot);
3860
                break;
3861
            case 0x83:
3862
                val = (int8_t)insn_get(s, OT_BYTE);
3863
                break;
3864
            }
3865
            gen_op_movl_T1_im(val);
3866
            gen_op(s, op, ot, opreg);
3867
        }
3868
        break;
3869

    
3870
        /**************************/
3871
        /* inc, dec, and other misc arith */
3872
    case 0x40 ... 0x47: /* inc Gv */
3873
        ot = dflag ? OT_LONG : OT_WORD;
3874
        gen_inc(s, ot, OR_EAX + (b & 7), 1);
3875
        break;
3876
    case 0x48 ... 0x4f: /* dec Gv */
3877
        ot = dflag ? OT_LONG : OT_WORD;
3878
        gen_inc(s, ot, OR_EAX + (b & 7), -1);
3879
        break;
3880
    case 0xf6: /* GRP3 */
3881
    case 0xf7:
3882
        if ((b & 1) == 0)
3883
            ot = OT_BYTE;
3884
        else
3885
            ot = dflag + OT_WORD;
3886

    
3887
        modrm = ldub_code(s->pc++);
3888
        mod = (modrm >> 6) & 3;
3889
        rm = (modrm & 7) | REX_B(s);
3890
        op = (modrm >> 3) & 7;
3891
        if (mod != 3) {
3892
            if (op == 0)
3893
                s->rip_offset = insn_const_size(ot);
3894
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3895
            gen_op_ld_T0_A0(ot + s->mem_index);
3896
        } else {
3897
            gen_op_mov_TN_reg(ot, 0, rm);
3898
        }
3899

    
3900
        switch(op) {
3901
        case 0: /* test */
3902
            val = insn_get(s, ot);
3903
            gen_op_movl_T1_im(val);
3904
            gen_op_testl_T0_T1_cc();
3905
            s->cc_op = CC_OP_LOGICB + ot;
3906
            break;
3907
        case 2: /* not */
3908
            tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
3909
            if (mod != 3) {
3910
                gen_op_st_T0_A0(ot + s->mem_index);
3911
            } else {
3912
                gen_op_mov_reg_T0(ot, rm);
3913
            }
3914
            break;
3915
        case 3: /* neg */
3916
            tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
3917
            if (mod != 3) {
3918
                gen_op_st_T0_A0(ot + s->mem_index);
3919
            } else {
3920
                gen_op_mov_reg_T0(ot, rm);
3921
            }
3922
            gen_op_update_neg_cc();
3923
            s->cc_op = CC_OP_SUBB + ot;
3924
            break;
3925
        case 4: /* mul */
3926
            switch(ot) {
3927
            case OT_BYTE:
3928
                gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX);
3929
                tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
3930
                tcg_gen_ext8u_tl(cpu_T[1], cpu_T[1]);
3931
                /* XXX: use 32 bit mul which could be faster */
3932
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3933
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
3934
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
3935
                tcg_gen_andi_tl(cpu_cc_src, cpu_T[0], 0xff00);
3936
                s->cc_op = CC_OP_MULB;
3937
                break;
3938
            case OT_WORD:
3939
                gen_op_mov_TN_reg(OT_WORD, 1, R_EAX);
3940
                tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
3941
                tcg_gen_ext16u_tl(cpu_T[1], cpu_T[1]);
3942
                /* XXX: use 32 bit mul which could be faster */
3943
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3944
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
3945
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
3946
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
3947
                gen_op_mov_reg_T0(OT_WORD, R_EDX);
3948
                tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
3949
                s->cc_op = CC_OP_MULW;
3950
                break;
3951
            default:
3952
            case OT_LONG:
3953
#ifdef TARGET_X86_64
3954
                gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
3955
                tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
3956
                tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
3957
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3958
                gen_op_mov_reg_T0(OT_LONG, R_EAX);
3959
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
3960
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
3961
                gen_op_mov_reg_T0(OT_LONG, R_EDX);
3962
                tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
3963
#else
3964
                {
3965
                    TCGv t0, t1;
3966
                    t0 = tcg_temp_new(TCG_TYPE_I64);
3967
                    t1 = tcg_temp_new(TCG_TYPE_I64);
3968
                    gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
3969
                    tcg_gen_extu_i32_i64(t0, cpu_T[0]);
3970
                    tcg_gen_extu_i32_i64(t1, cpu_T[1]);
3971
                    tcg_gen_mul_i64(t0, t0, t1);
3972
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
3973
                    gen_op_mov_reg_T0(OT_LONG, R_EAX);
3974
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
3975
                    tcg_gen_shri_i64(t0, t0, 32);
3976
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
3977
                    gen_op_mov_reg_T0(OT_LONG, R_EDX);
3978
                    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
3979
                }
3980
#endif
3981
                s->cc_op = CC_OP_MULL;
3982
                break;
3983
#ifdef TARGET_X86_64
3984
            case OT_QUAD:
3985
                tcg_gen_helper_0_1(helper_mulq_EAX_T0, cpu_T[0]);
3986
                s->cc_op = CC_OP_MULQ;
3987
                break;
3988
#endif
3989
            }
3990
            break;
3991
        case 5: /* imul */
3992
            switch(ot) {
3993
            case OT_BYTE:
3994
                gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX);
3995
                tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
3996
                tcg_gen_ext8s_tl(cpu_T[1], cpu_T[1]);
3997
                /* XXX: use 32 bit mul which could be faster */
3998
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3999
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
4000
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4001
                tcg_gen_ext8s_tl(cpu_tmp0, cpu_T[0]);
4002
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4003
                s->cc_op = CC_OP_MULB;
4004
                break;
4005
            case OT_WORD:
4006
                gen_op_mov_TN_reg(OT_WORD, 1, R_EAX);
4007
                tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4008
                tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
4009
                /* XXX: use 32 bit mul which could be faster */
4010
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4011
                gen_op_mov_reg_T0(OT_WORD, R_EAX);
4012
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4013
                tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
4014
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4015
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
4016
                gen_op_mov_reg_T0(OT_WORD, R_EDX);
4017
                s->cc_op = CC_OP_MULW;
4018
                break;
4019
            default:
4020
            case OT_LONG:
4021
#ifdef TARGET_X86_64
4022
                gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4023
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4024
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
4025
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4026
                gen_op_mov_reg_T0(OT_LONG, R_EAX);
4027
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4028
                tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
4029
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4030
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
4031
                gen_op_mov_reg_T0(OT_LONG, R_EDX);
4032
#else
4033
                {
4034
                    TCGv t0, t1;
4035
                    t0 = tcg_temp_new(TCG_TYPE_I64);
4036
                    t1 = tcg_temp_new(TCG_TYPE_I64);
4037
                    gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4038
                    tcg_gen_ext_i32_i64(t0, cpu_T[0]);
4039
                    tcg_gen_ext_i32_i64(t1, cpu_T[1]);
4040
                    tcg_gen_mul_i64(t0, t0, t1);
4041
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4042
                    gen_op_mov_reg_T0(OT_LONG, R_EAX);
4043
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4044
                    tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
4045
                    tcg_gen_shri_i64(t0, t0, 32);
4046
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4047
                    gen_op_mov_reg_T0(OT_LONG, R_EDX);
4048
                    tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4049
                }
4050
#endif
4051
                s->cc_op = CC_OP_MULL;
4052
                break;
4053
#ifdef TARGET_X86_64
4054
            case OT_QUAD:
4055
                tcg_gen_helper_0_1(helper_imulq_EAX_T0, cpu_T[0]);
4056
                s->cc_op = CC_OP_MULQ;
4057
                break;
4058
#endif
4059
            }
4060
            break;
4061
        case 6: /* div */
4062
            switch(ot) {
4063
            case OT_BYTE:
4064
                gen_jmp_im(pc_start - s->cs_base);
4065
                tcg_gen_helper_0_1(helper_divb_AL, cpu_T[0]);
4066
                break;
4067
            case OT_WORD:
4068
                gen_jmp_im(pc_start - s->cs_base);
4069
                tcg_gen_helper_0_1(helper_divw_AX, cpu_T[0]);
4070
                break;
4071
            default:
4072
            case OT_LONG:
4073
                gen_jmp_im(pc_start - s->cs_base);
4074
                tcg_gen_helper_0_1(helper_divl_EAX, cpu_T[0]);
4075
                break;
4076
#ifdef TARGET_X86_64
4077
            case OT_QUAD:
4078
                gen_jmp_im(pc_start - s->cs_base);
4079
                tcg_gen_helper_0_1(helper_divq_EAX, cpu_T[0]);
4080
                break;
4081
#endif
4082
            }
4083
            break;
4084
        case 7: /* idiv */
4085
            switch(ot) {
4086
            case OT_BYTE:
4087
                gen_jmp_im(pc_start - s->cs_base);
4088
                tcg_gen_helper_0_1(helper_idivb_AL, cpu_T[0]);
4089
                break;
4090
            case OT_WORD:
4091
                gen_jmp_im(pc_start - s->cs_base);
4092
                tcg_gen_helper_0_1(helper_idivw_AX, cpu_T[0]);
4093
                break;
4094
            default:
4095
            case OT_LONG:
4096
                gen_jmp_im(pc_start - s->cs_base);
4097
                tcg_gen_helper_0_1(helper_idivl_EAX, cpu_T[0]);
4098
                break;
4099
#ifdef TARGET_X86_64
4100
            case OT_QUAD:
4101
                gen_jmp_im(pc_start - s->cs_base);
4102
                tcg_gen_helper_0_1(helper_idivq_EAX, cpu_T[0]);
4103
                break;
4104
#endif
4105
            }
4106
            break;
4107
        default:
4108
            goto illegal_op;
4109
        }
4110
        break;
4111

    
4112
    case 0xfe: /* GRP4 */
4113
    case 0xff: /* GRP5 */
4114
        if ((b & 1) == 0)
4115
            ot = OT_BYTE;
4116
        else
4117
            ot = dflag + OT_WORD;
4118

    
4119
        modrm = ldub_code(s->pc++);
4120
        mod = (modrm >> 6) & 3;
4121
        rm = (modrm & 7) | REX_B(s);
4122
        op = (modrm >> 3) & 7;
4123
        if (op >= 2 && b == 0xfe) {
4124
            goto illegal_op;
4125
        }
4126
        if (CODE64(s)) {
4127
            if (op == 2 || op == 4) {
4128
                /* operand size for jumps is 64 bit */
4129
                ot = OT_QUAD;
4130
            } else if (op == 3 || op == 5) {
4131
                /* for call calls, the operand is 16 or 32 bit, even
4132
                   in long mode */
4133
                ot = dflag ? OT_LONG : OT_WORD;
4134
            } else if (op == 6) {
4135
                /* default push size is 64 bit */
4136
                ot = dflag ? OT_QUAD : OT_WORD;
4137
            }
4138
        }
4139
        if (mod != 3) {
4140
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4141
            if (op >= 2 && op != 3 && op != 5)
4142
                gen_op_ld_T0_A0(ot + s->mem_index);
4143
        } else {
4144
            gen_op_mov_TN_reg(ot, 0, rm);
4145
        }
4146

    
4147
        switch(op) {
4148
        case 0: /* inc Ev */
4149
            if (mod != 3)
4150
                opreg = OR_TMP0;
4151
            else
4152
                opreg = rm;
4153
            gen_inc(s, ot, opreg, 1);
4154
            break;
4155
        case 1: /* dec Ev */
4156
            if (mod != 3)
4157
                opreg = OR_TMP0;
4158
            else
4159
                opreg = rm;
4160
            gen_inc(s, ot, opreg, -1);
4161
            break;
4162
        case 2: /* call Ev */
4163
            /* XXX: optimize if memory (no 'and' is necessary) */
4164
            if (s->dflag == 0)
4165
                gen_op_andl_T0_ffff();
4166
            next_eip = s->pc - s->cs_base;
4167
            gen_movtl_T1_im(next_eip);
4168
            gen_push_T1(s);
4169
            gen_op_jmp_T0();
4170
            gen_eob(s);
4171
            break;
4172
        case 3: /* lcall Ev */
4173
            gen_op_ld_T1_A0(ot + s->mem_index);
4174
            gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4175
            gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
4176
        do_lcall:
4177
            if (s->pe && !s->vm86) {
4178
                if (s->cc_op != CC_OP_DYNAMIC)
4179
                    gen_op_set_cc_op(s->cc_op);
4180
                gen_jmp_im(pc_start - s->cs_base);
4181
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4182
                tcg_gen_helper_0_4(helper_lcall_protected,
4183
                                   cpu_tmp2_i32, cpu_T[1],
4184
                                   tcg_const_i32(dflag), 
4185
                                   tcg_const_i32(s->pc - pc_start));
4186
            } else {
4187
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4188
                tcg_gen_helper_0_4(helper_lcall_real,
4189
                                   cpu_tmp2_i32, cpu_T[1],
4190
                                   tcg_const_i32(dflag), 
4191
                                   tcg_const_i32(s->pc - s->cs_base));
4192
            }
4193
            gen_eob(s);
4194
            break;
4195
        case 4: /* jmp Ev */
4196
            if (s->dflag == 0)
4197
                gen_op_andl_T0_ffff();
4198
            gen_op_jmp_T0();
4199
            gen_eob(s);
4200
            break;
4201
        case 5: /* ljmp Ev */
4202
            gen_op_ld_T1_A0(ot + s->mem_index);
4203
            gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4204
            gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
4205
        do_ljmp:
4206
            if (s->pe && !s->vm86) {
4207
                if (s->cc_op != CC_OP_DYNAMIC)
4208
                    gen_op_set_cc_op(s->cc_op);
4209
                gen_jmp_im(pc_start - s->cs_base);
4210
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4211
                tcg_gen_helper_0_3(helper_ljmp_protected,
4212
                                   cpu_tmp2_i32,
4213
                                   cpu_T[1],
4214
                                   tcg_const_i32(s->pc - pc_start));
4215
            } else {
4216
                gen_op_movl_seg_T0_vm(R_CS);
4217
                gen_op_movl_T0_T1();
4218
                gen_op_jmp_T0();
4219
            }
4220
            gen_eob(s);
4221
            break;
4222
        case 6: /* push Ev */
4223
            gen_push_T0(s);
4224
            break;
4225
        default:
4226
            goto illegal_op;
4227
        }
4228
        break;
4229

    
4230
    case 0x84: /* test Ev, Gv */
4231
    case 0x85:
4232
        if ((b & 1) == 0)
4233
            ot = OT_BYTE;
4234
        else
4235
            ot = dflag + OT_WORD;
4236

    
4237
        modrm = ldub_code(s->pc++);
4238
        mod = (modrm >> 6) & 3;
4239
        rm = (modrm & 7) | REX_B(s);
4240
        reg = ((modrm >> 3) & 7) | rex_r;
4241

    
4242
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
4243
        gen_op_mov_TN_reg(ot, 1, reg);
4244
        gen_op_testl_T0_T1_cc();
4245
        s->cc_op = CC_OP_LOGICB + ot;
4246
        break;
4247

    
4248
    case 0xa8: /* test eAX, Iv */
4249
    case 0xa9:
4250
        if ((b & 1) == 0)
4251
            ot = OT_BYTE;
4252
        else
4253
            ot = dflag + OT_WORD;
4254
        val = insn_get(s, ot);
4255

    
4256
        gen_op_mov_TN_reg(ot, 0, OR_EAX);
4257
        gen_op_movl_T1_im(val);
4258
        gen_op_testl_T0_T1_cc();
4259
        s->cc_op = CC_OP_LOGICB + ot;
4260
        break;
4261

    
4262
    case 0x98: /* CWDE/CBW */
4263
#ifdef TARGET_X86_64
4264
        if (dflag == 2) {
4265
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
4266
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4267
            gen_op_mov_reg_T0(OT_QUAD, R_EAX);
4268
        } else
4269
#endif
4270
        if (dflag == 1) {
4271
            gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
4272
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4273
            gen_op_mov_reg_T0(OT_LONG, R_EAX);
4274
        } else {
4275
            gen_op_mov_TN_reg(OT_BYTE, 0, R_EAX);
4276
            tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
4277
            gen_op_mov_reg_T0(OT_WORD, R_EAX);
4278
        }
4279
        break;
4280
    case 0x99: /* CDQ/CWD */
4281
#ifdef TARGET_X86_64
4282
        if (dflag == 2) {
4283
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
4284
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 63);
4285
            gen_op_mov_reg_T0(OT_QUAD, R_EDX);
4286
        } else
4287
#endif
4288
        if (dflag == 1) {
4289
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
4290
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4291
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 31);
4292
            gen_op_mov_reg_T0(OT_LONG, R_EDX);
4293
        } else {
4294
            gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
4295
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4296
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 15);
4297
            gen_op_mov_reg_T0(OT_WORD, R_EDX);
4298
        }
4299
        break;
4300
    case 0x1af: /* imul Gv, Ev */
4301
    case 0x69: /* imul Gv, Ev, I */
4302
    case 0x6b:
4303
        ot = dflag + OT_WORD;
4304
        modrm = ldub_code(s->pc++);
4305
        reg = ((modrm >> 3) & 7) | rex_r;
4306
        if (b == 0x69)
4307
            s->rip_offset = insn_const_size(ot);
4308
        else if (b == 0x6b)
4309
            s->rip_offset = 1;
4310
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
4311
        if (b == 0x69) {
4312
            val = insn_get(s, ot);
4313
            gen_op_movl_T1_im(val);
4314
        } else if (b == 0x6b) {
4315
            val = (int8_t)insn_get(s, OT_BYTE);
4316
            gen_op_movl_T1_im(val);
4317
        } else {
4318
            gen_op_mov_TN_reg(ot, 1, reg);
4319
        }
4320

    
4321
#ifdef TARGET_X86_64
4322
        if (ot == OT_QUAD) {
4323
            tcg_gen_helper_1_2(helper_imulq_T0_T1, cpu_T[0], cpu_T[0], cpu_T[1]);
4324
        } else
4325
#endif
4326
        if (ot == OT_LONG) {
4327
#ifdef TARGET_X86_64
4328
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4329
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
4330
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4331
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4332
                tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
4333
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4334
#else
4335
                {
4336
                    TCGv t0, t1;
4337
                    t0 = tcg_temp_new(TCG_TYPE_I64);
4338
                    t1 = tcg_temp_new(TCG_TYPE_I64);
4339
                    tcg_gen_ext_i32_i64(t0, cpu_T[0]);
4340
                    tcg_gen_ext_i32_i64(t1, cpu_T[1]);
4341
                    tcg_gen_mul_i64(t0, t0, t1);
4342
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4343
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4344
                    tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
4345
                    tcg_gen_shri_i64(t0, t0, 32);
4346
                    tcg_gen_trunc_i64_i32(cpu_T[1], t0);
4347
                    tcg_gen_sub_tl(cpu_cc_src, cpu_T[1], cpu_tmp0);
4348
                }
4349
#endif
4350
        } else {
4351
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4352
            tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
4353
            /* XXX: use 32 bit mul which could be faster */
4354
            tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4355
            tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4356
            tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
4357
            tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4358
        }
4359
        gen_op_mov_reg_T0(ot, reg);
4360
        s->cc_op = CC_OP_MULB + ot;
4361
        break;
4362
    case 0x1c0:
4363
    case 0x1c1: /* xadd Ev, Gv */
4364
        if ((b & 1) == 0)
4365
            ot = OT_BYTE;
4366
        else
4367
            ot = dflag + OT_WORD;
4368
        modrm = ldub_code(s->pc++);
4369
        reg = ((modrm >> 3) & 7) | rex_r;
4370
        mod = (modrm >> 6) & 3;
4371
        if (mod == 3) {
4372
            rm = (modrm & 7) | REX_B(s);
4373
            gen_op_mov_TN_reg(ot, 0, reg);
4374
            gen_op_mov_TN_reg(ot, 1, rm);
4375
            gen_op_addl_T0_T1();
4376
            gen_op_mov_reg_T1(ot, reg);
4377
            gen_op_mov_reg_T0(ot, rm);
4378
        } else {
4379
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4380
            gen_op_mov_TN_reg(ot, 0, reg);
4381
            gen_op_ld_T1_A0(ot + s->mem_index);
4382
            gen_op_addl_T0_T1();
4383
            gen_op_st_T0_A0(ot + s->mem_index);
4384
            gen_op_mov_reg_T1(ot, reg);
4385
        }
4386
        gen_op_update2_cc();
4387
        s->cc_op = CC_OP_ADDB + ot;
4388
        break;
4389
    case 0x1b0:
4390
    case 0x1b1: /* cmpxchg Ev, Gv */
4391
        {
4392
            int label1, label2;
4393
            TCGv t0, t1, t2, a0;
4394

    
4395
            if ((b & 1) == 0)
4396
                ot = OT_BYTE;
4397
            else
4398
                ot = dflag + OT_WORD;
4399
            modrm = ldub_code(s->pc++);
4400
            reg = ((modrm >> 3) & 7) | rex_r;
4401
            mod = (modrm >> 6) & 3;
4402
            t0 = tcg_temp_local_new(TCG_TYPE_TL);
4403
            t1 = tcg_temp_local_new(TCG_TYPE_TL);
4404
            t2 = tcg_temp_local_new(TCG_TYPE_TL);
4405
            a0 = tcg_temp_local_new(TCG_TYPE_TL);
4406
            gen_op_mov_v_reg(ot, t1, reg);
4407
            if (mod == 3) {
4408
                rm = (modrm & 7) | REX_B(s);
4409
                gen_op_mov_v_reg(ot, t0, rm);
4410
            } else {
4411
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4412
                tcg_gen_mov_tl(a0, cpu_A0);
4413
                gen_op_ld_v(ot + s->mem_index, t0, a0);
4414
                rm = 0; /* avoid warning */
4415
            }
4416
            label1 = gen_new_label();
4417
            tcg_gen_ld_tl(t2, cpu_env, offsetof(CPUState, regs[R_EAX]));
4418
            tcg_gen_sub_tl(t2, t2, t0);
4419
            gen_extu(ot, t2);
4420
            tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
4421
            if (mod == 3) {
4422
                label2 = gen_new_label();
4423
                gen_op_mov_reg_v(ot, R_EAX, t0);
4424
                tcg_gen_br(label2);
4425
                gen_set_label(label1);
4426
                gen_op_mov_reg_v(ot, rm, t1);
4427
                gen_set_label(label2);
4428
            } else {
4429
                tcg_gen_mov_tl(t1, t0);
4430
                gen_op_mov_reg_v(ot, R_EAX, t0);
4431
                gen_set_label(label1);
4432
                /* always store */
4433
                gen_op_st_v(ot + s->mem_index, t1, a0);
4434
            }
4435
            tcg_gen_mov_tl(cpu_cc_src, t0);
4436
            tcg_gen_mov_tl(cpu_cc_dst, t2);
4437
            s->cc_op = CC_OP_SUBB + ot;
4438
            tcg_temp_free(t0);
4439
            tcg_temp_free(t1);
4440
            tcg_temp_free(t2);
4441
            tcg_temp_free(a0);
4442
        }
4443
        break;
4444
    case 0x1c7: /* cmpxchg8b */
4445
        modrm = ldub_code(s->pc++);
4446
        mod = (modrm >> 6) & 3;
4447
        if ((mod == 3) || ((modrm & 0x38) != 0x8))
4448
            goto illegal_op;
4449
#ifdef TARGET_X86_64
4450
        if (dflag == 2) {
4451
            if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
4452
                goto illegal_op;
4453
            gen_jmp_im(pc_start - s->cs_base);
4454
            if (s->cc_op != CC_OP_DYNAMIC)
4455
                gen_op_set_cc_op(s->cc_op);
4456
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4457
            tcg_gen_helper_0_1(helper_cmpxchg16b, cpu_A0);
4458
        } else
4459
#endif        
4460
        {
4461
            if (!(s->cpuid_features & CPUID_CX8))
4462
                goto illegal_op;
4463
            gen_jmp_im(pc_start - s->cs_base);
4464
            if (s->cc_op != CC_OP_DYNAMIC)
4465
                gen_op_set_cc_op(s->cc_op);
4466
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4467
            tcg_gen_helper_0_1(helper_cmpxchg8b, cpu_A0);
4468
        }
4469
        s->cc_op = CC_OP_EFLAGS;
4470
        break;
4471

    
4472
        /**************************/
4473
        /* push/pop */
4474
    case 0x50 ... 0x57: /* push */
4475
        gen_op_mov_TN_reg(OT_LONG, 0, (b & 7) | REX_B(s));
4476
        gen_push_T0(s);
4477
        break;
4478
    case 0x58 ... 0x5f: /* pop */
4479
        if (CODE64(s)) {
4480
            ot = dflag ? OT_QUAD : OT_WORD;
4481
        } else {
4482
            ot = dflag + OT_WORD;
4483
        }
4484
        gen_pop_T0(s);
4485
        /* NOTE: order is important for pop %sp */
4486
        gen_pop_update(s);
4487
        gen_op_mov_reg_T0(ot, (b & 7) | REX_B(s));
4488
        break;
4489
    case 0x60: /* pusha */
4490
        if (CODE64(s))
4491
            goto illegal_op;
4492
        gen_pusha(s);
4493
        break;
4494
    case 0x61: /* popa */
4495
        if (CODE64(s))
4496
            goto illegal_op;
4497
        gen_popa(s);
4498
        break;
4499
    case 0x68: /* push Iv */
4500
    case 0x6a:
4501
        if (CODE64(s)) {
4502
            ot = dflag ? OT_QUAD : OT_WORD;
4503
        } else {
4504
            ot = dflag + OT_WORD;
4505
        }
4506
        if (b == 0x68)
4507
            val = insn_get(s, ot);
4508
        else
4509
            val = (int8_t)insn_get(s, OT_BYTE);
4510
        gen_op_movl_T0_im(val);
4511
        gen_push_T0(s);
4512
        break;
4513
    case 0x8f: /* pop Ev */
4514
        if (CODE64(s)) {
4515
            ot = dflag ? OT_QUAD : OT_WORD;
4516
        } else {
4517
            ot = dflag + OT_WORD;
4518
        }
4519
        modrm = ldub_code(s->pc++);
4520
        mod = (modrm >> 6) & 3;
4521
        gen_pop_T0(s);
4522
        if (mod == 3) {
4523
            /* NOTE: order is important for pop %sp */
4524
            gen_pop_update(s);
4525
            rm = (modrm & 7) | REX_B(s);
4526
            gen_op_mov_reg_T0(ot, rm);
4527
        } else {
4528
            /* NOTE: order is important too for MMU exceptions */
4529
            s->popl_esp_hack = 1 << ot;
4530
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
4531
            s->popl_esp_hack = 0;
4532
            gen_pop_update(s);
4533
        }
4534
        break;
4535
    case 0xc8: /* enter */
4536
        {
4537
            int level;
4538
            val = lduw_code(s->pc);
4539
            s->pc += 2;
4540
            level = ldub_code(s->pc++);
4541
            gen_enter(s, val, level);
4542
        }
4543
        break;
4544
    case 0xc9: /* leave */
4545
        /* XXX: exception not precise (ESP is updated before potential exception) */
4546
        if (CODE64(s)) {
4547
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EBP);
4548
            gen_op_mov_reg_T0(OT_QUAD, R_ESP);
4549
        } else if (s->ss32) {
4550
            gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
4551
            gen_op_mov_reg_T0(OT_LONG, R_ESP);
4552
        } else {
4553
            gen_op_mov_TN_reg(OT_WORD, 0, R_EBP);
4554
            gen_op_mov_reg_T0(OT_WORD, R_ESP);
4555
        }
4556
        gen_pop_T0(s);
4557
        if (CODE64(s)) {
4558
            ot = dflag ? OT_QUAD : OT_WORD;
4559
        } else {
4560
            ot = dflag + OT_WORD;
4561
        }
4562
        gen_op_mov_reg_T0(ot, R_EBP);
4563
        gen_pop_update(s);
4564
        break;
4565
    case 0x06: /* push es */
4566
    case 0x0e: /* push cs */
4567
    case 0x16: /* push ss */
4568
    case 0x1e: /* push ds */
4569
        if (CODE64(s))
4570
            goto illegal_op;
4571
        gen_op_movl_T0_seg(b >> 3);
4572
        gen_push_T0(s);
4573
        break;
4574
    case 0x1a0: /* push fs */
4575
    case 0x1a8: /* push gs */
4576
        gen_op_movl_T0_seg((b >> 3) & 7);
4577
        gen_push_T0(s);
4578
        break;
4579
    case 0x07: /* pop es */
4580
    case 0x17: /* pop ss */
4581
    case 0x1f: /* pop ds */
4582
        if (CODE64(s))
4583
            goto illegal_op;
4584
        reg = b >> 3;
4585
        gen_pop_T0(s);
4586
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
4587
        gen_pop_update(s);
4588
        if (reg == R_SS) {
4589
            /* if reg == SS, inhibit interrupts/trace. */
4590
            /* If several instructions disable interrupts, only the
4591
               _first_ does it */
4592
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
4593
                tcg_gen_helper_0_0(helper_set_inhibit_irq);
4594
            s->tf = 0;
4595
        }
4596
        if (s->is_jmp) {
4597
            gen_jmp_im(s->pc - s->cs_base);
4598
            gen_eob(s);
4599
        }
4600
        break;
4601
    case 0x1a1: /* pop fs */
4602
    case 0x1a9: /* pop gs */
4603
        gen_pop_T0(s);
4604
        gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
4605
        gen_pop_update(s);
4606
        if (s->is_jmp) {
4607
            gen_jmp_im(s->pc - s->cs_base);
4608
            gen_eob(s);
4609
        }
4610
        break;
4611

    
4612
        /**************************/
4613
        /* mov */
4614
    case 0x88:
4615
    case 0x89: /* mov Gv, Ev */
4616
        if ((b & 1) == 0)
4617
            ot = OT_BYTE;
4618
        else
4619
            ot = dflag + OT_WORD;
4620
        modrm = ldub_code(s->pc++);
4621
        reg = ((modrm >> 3) & 7) | rex_r;
4622

    
4623
        /* generate a generic store */
4624
        gen_ldst_modrm(s, modrm, ot, reg, 1);
4625
        break;
4626
    case 0xc6:
4627
    case 0xc7: /* mov Ev, Iv */
4628
        if ((b & 1) == 0)
4629
            ot = OT_BYTE;
4630
        else
4631
            ot = dflag + OT_WORD;
4632
        modrm = ldub_code(s->pc++);
4633
        mod = (modrm >> 6) & 3;
4634
        if (mod != 3) {
4635
            s->rip_offset = insn_const_size(ot);
4636
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4637
        }
4638
        val = insn_get(s, ot);
4639
        gen_op_movl_T0_im(val);
4640
        if (mod != 3)
4641
            gen_op_st_T0_A0(ot + s->mem_index);
4642
        else
4643
            gen_op_mov_reg_T0(ot, (modrm & 7) | REX_B(s));
4644
        break;
4645
    case 0x8a:
4646
    case 0x8b: /* mov Ev, Gv */
4647
        if ((b & 1) == 0)
4648
            ot = OT_BYTE;
4649
        else
4650
            ot = OT_WORD + dflag;
4651
        modrm = ldub_code(s->pc++);
4652
        reg = ((modrm >> 3) & 7) | rex_r;
4653

    
4654
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
4655
        gen_op_mov_reg_T0(ot, reg);
4656
        break;
4657
    case 0x8e: /* mov seg, Gv */
4658
        modrm = ldub_code(s->pc++);
4659
        reg = (modrm >> 3) & 7;
4660
        if (reg >= 6 || reg == R_CS)
4661
            goto illegal_op;
4662
        gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
4663
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
4664
        if (reg == R_SS) {
4665
            /* if reg == SS, inhibit interrupts/trace */
4666
            /* If several instructions disable interrupts, only the
4667
               _first_ does it */
4668
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
4669
                tcg_gen_helper_0_0(helper_set_inhibit_irq);
4670
            s->tf = 0;
4671
        }
4672
        if (s->is_jmp) {
4673
            gen_jmp_im(s->pc - s->cs_base);
4674
            gen_eob(s);
4675
        }
4676
        break;
4677
    case 0x8c: /* mov Gv, seg */
4678
        modrm = ldub_code(s->pc++);
4679
        reg = (modrm >> 3) & 7;
4680
        mod = (modrm >> 6) & 3;
4681
        if (reg >= 6)
4682
            goto illegal_op;
4683
        gen_op_movl_T0_seg(reg);
4684
        if (mod == 3)
4685
            ot = OT_WORD + dflag;
4686
        else
4687
            ot = OT_WORD;
4688
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
4689
        break;
4690

    
4691
    case 0x1b6: /* movzbS Gv, Eb */
4692
    case 0x1b7: /* movzwS Gv, Eb */
4693
    case 0x1be: /* movsbS Gv, Eb */
4694
    case 0x1bf: /* movswS Gv, Eb */
4695
        {
4696
            int d_ot;
4697
            /* d_ot is the size of destination */
4698
            d_ot = dflag + OT_WORD;
4699
            /* ot is the size of source */
4700
            ot = (b & 1) + OT_BYTE;
4701
            modrm = ldub_code(s->pc++);
4702
            reg = ((modrm >> 3) & 7) | rex_r;
4703
            mod = (modrm >> 6) & 3;
4704
            rm = (modrm & 7) | REX_B(s);
4705

    
4706
            if (mod == 3) {
4707
                gen_op_mov_TN_reg(ot, 0, rm);
4708
                switch(ot | (b & 8)) {
4709
                case OT_BYTE:
4710
                    tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
4711
                    break;
4712
                case OT_BYTE | 8:
4713
                    tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
4714
                    break;
4715
                case OT_WORD:
4716
                    tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
4717
                    break;
4718
                default:
4719
                case OT_WORD | 8:
4720
                    tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4721
                    break;
4722
                }
4723
                gen_op_mov_reg_T0(d_ot, reg);
4724
            } else {
4725
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4726
                if (b & 8) {
4727
                    gen_op_lds_T0_A0(ot + s->mem_index);
4728
                } else {
4729
                    gen_op_ldu_T0_A0(ot + s->mem_index);
4730
                }
4731
                gen_op_mov_reg_T0(d_ot, reg);
4732
            }
4733
        }
4734
        break;
4735

    
4736
    case 0x8d: /* lea */
4737
        ot = dflag + OT_WORD;
4738
        modrm = ldub_code(s->pc++);
4739
        mod = (modrm >> 6) & 3;
4740
        if (mod == 3)
4741
            goto illegal_op;
4742
        reg = ((modrm >> 3) & 7) | rex_r;
4743
        /* we must ensure that no segment is added */
4744
        s->override = -1;
4745
        val = s->addseg;
4746
        s->addseg = 0;
4747
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4748
        s->addseg = val;
4749
        gen_op_mov_reg_A0(ot - OT_WORD, reg);
4750
        break;
4751

    
4752
    case 0xa0: /* mov EAX, Ov */
4753
    case 0xa1:
4754
    case 0xa2: /* mov Ov, EAX */
4755
    case 0xa3:
4756
        {
4757
            target_ulong offset_addr;
4758

    
4759
            if ((b & 1) == 0)
4760
                ot = OT_BYTE;
4761
            else
4762
                ot = dflag + OT_WORD;
4763
#ifdef TARGET_X86_64
4764
            if (s->aflag == 2) {
4765
                offset_addr = ldq_code(s->pc);
4766
                s->pc += 8;
4767
                gen_op_movq_A0_im(offset_addr);
4768
            } else
4769
#endif
4770
            {
4771
                if (s->aflag) {
4772
                    offset_addr = insn_get(s, OT_LONG);
4773
                } else {
4774
                    offset_addr = insn_get(s, OT_WORD);
4775
                }
4776
                gen_op_movl_A0_im(offset_addr);
4777
            }
4778
            gen_add_A0_ds_seg(s);
4779
            if ((b & 2) == 0) {
4780
                gen_op_ld_T0_A0(ot + s->mem_index);
4781
                gen_op_mov_reg_T0(ot, R_EAX);
4782
            } else {
4783
                gen_op_mov_TN_reg(ot, 0, R_EAX);
4784
                gen_op_st_T0_A0(ot + s->mem_index);
4785
            }
4786
        }
4787
        break;
4788
    case 0xd7: /* xlat */
4789
#ifdef TARGET_X86_64
4790
        if (s->aflag == 2) {
4791
            gen_op_movq_A0_reg(R_EBX);
4792
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
4793
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
4794
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
4795
        } else
4796
#endif
4797
        {
4798
            gen_op_movl_A0_reg(R_EBX);
4799
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
4800
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
4801
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
4802
            if (s->aflag == 0)
4803
                gen_op_andl_A0_ffff();
4804
            else
4805
                tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
4806
        }
4807
        gen_add_A0_ds_seg(s);
4808
        gen_op_ldu_T0_A0(OT_BYTE + s->mem_index);
4809
        gen_op_mov_reg_T0(OT_BYTE, R_EAX);
4810
        break;
4811
    case 0xb0 ... 0xb7: /* mov R, Ib */
4812
        val = insn_get(s, OT_BYTE);
4813
        gen_op_movl_T0_im(val);
4814
        gen_op_mov_reg_T0(OT_BYTE, (b & 7) | REX_B(s));
4815
        break;
4816
    case 0xb8 ... 0xbf: /* mov R, Iv */
4817
#ifdef TARGET_X86_64
4818
        if (dflag == 2) {
4819
            uint64_t tmp;
4820
            /* 64 bit case */
4821
            tmp = ldq_code(s->pc);
4822
            s->pc += 8;
4823
            reg = (b & 7) | REX_B(s);
4824
            gen_movtl_T0_im(tmp);
4825
            gen_op_mov_reg_T0(OT_QUAD, reg);
4826
        } else
4827
#endif
4828
        {
4829
            ot = dflag ? OT_LONG : OT_WORD;
4830
            val = insn_get(s, ot);
4831
            reg = (b & 7) | REX_B(s);
4832
            gen_op_movl_T0_im(val);
4833
            gen_op_mov_reg_T0(ot, reg);
4834
        }
4835
        break;
4836

    
4837
    case 0x91 ... 0x97: /* xchg R, EAX */
4838
        ot = dflag + OT_WORD;
4839
        reg = (b & 7) | REX_B(s);
4840
        rm = R_EAX;
4841
        goto do_xchg_reg;
4842
    case 0x86:
4843
    case 0x87: /* xchg Ev, Gv */
4844
        if ((b & 1) == 0)
4845
            ot = OT_BYTE;
4846
        else
4847
            ot = dflag + OT_WORD;
4848
        modrm = ldub_code(s->pc++);
4849
        reg = ((modrm >> 3) & 7) | rex_r;
4850
        mod = (modrm >> 6) & 3;
4851
        if (mod == 3) {
4852
            rm = (modrm & 7) | REX_B(s);
4853
        do_xchg_reg:
4854
            gen_op_mov_TN_reg(ot, 0, reg);
4855
            gen_op_mov_TN_reg(ot, 1, rm);
4856
            gen_op_mov_reg_T0(ot, rm);
4857
            gen_op_mov_reg_T1(ot, reg);
4858
        } else {
4859
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4860
            gen_op_mov_TN_reg(ot, 0, reg);
4861
            /* for xchg, lock is implicit */
4862
            if (!(prefixes & PREFIX_LOCK))
4863
                tcg_gen_helper_0_0(helper_lock);
4864
            gen_op_ld_T1_A0(ot + s->mem_index);
4865
            gen_op_st_T0_A0(ot + s->mem_index);
4866
            if (!(prefixes & PREFIX_LOCK))
4867
                tcg_gen_helper_0_0(helper_unlock);
4868
            gen_op_mov_reg_T1(ot, reg);
4869
        }
4870
        break;
4871
    case 0xc4: /* les Gv */
4872
        if (CODE64(s))
4873
            goto illegal_op;
4874
        op = R_ES;
4875
        goto do_lxx;
4876
    case 0xc5: /* lds Gv */
4877
        if (CODE64(s))
4878
            goto illegal_op;
4879
        op = R_DS;
4880
        goto do_lxx;
4881
    case 0x1b2: /* lss Gv */
4882
        op = R_SS;
4883
        goto do_lxx;
4884
    case 0x1b4: /* lfs Gv */
4885
        op = R_FS;
4886
        goto do_lxx;
4887
    case 0x1b5: /* lgs Gv */
4888
        op = R_GS;
4889
    do_lxx:
4890
        ot = dflag ? OT_LONG : OT_WORD;
4891
        modrm = ldub_code(s->pc++);
4892
        reg = ((modrm >> 3) & 7) | rex_r;
4893
        mod = (modrm >> 6) & 3;
4894
        if (mod == 3)
4895
            goto illegal_op;
4896
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4897
        gen_op_ld_T1_A0(ot + s->mem_index);
4898
        gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4899
        /* load the segment first to handle exceptions properly */
4900
        gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
4901
        gen_movl_seg_T0(s, op, pc_start - s->cs_base);
4902
        /* then put the data */
4903
        gen_op_mov_reg_T1(ot, reg);
4904
        if (s->is_jmp) {
4905
            gen_jmp_im(s->pc - s->cs_base);
4906
            gen_eob(s);
4907
        }
4908
        break;
4909

    
4910
        /************************/
4911
        /* shifts */
4912
    case 0xc0:
4913
    case 0xc1:
4914
        /* shift Ev,Ib */
4915
        shift = 2;
4916
    grp2:
4917
        {
4918
            if ((b & 1) == 0)
4919
                ot = OT_BYTE;
4920
            else
4921
                ot = dflag + OT_WORD;
4922

    
4923
            modrm = ldub_code(s->pc++);
4924
            mod = (modrm >> 6) & 3;
4925
            op = (modrm >> 3) & 7;
4926

    
4927
            if (mod != 3) {
4928
                if (shift == 2) {
4929
                    s->rip_offset = 1;
4930
                }
4931
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4932
                opreg = OR_TMP0;
4933
            } else {
4934
                opreg = (modrm & 7) | REX_B(s);
4935
            }
4936

    
4937
            /* simpler op */
4938
            if (shift == 0) {
4939
                gen_shift(s, op, ot, opreg, OR_ECX);
4940
            } else {
4941
                if (shift == 2) {
4942
                    shift = ldub_code(s->pc++);
4943
                }
4944
                gen_shifti(s, op, ot, opreg, shift);
4945
            }
4946
        }
4947
        break;
4948
    case 0xd0:
4949
    case 0xd1:
4950
        /* shift Ev,1 */
4951
        shift = 1;
4952
        goto grp2;
4953
    case 0xd2:
4954
    case 0xd3:
4955
        /* shift Ev,cl */
4956
        shift = 0;
4957
        goto grp2;
4958

    
4959
    case 0x1a4: /* shld imm */
4960
        op = 0;
4961
        shift = 1;
4962
        goto do_shiftd;
4963
    case 0x1a5: /* shld cl */
4964
        op = 0;
4965
        shift = 0;
4966
        goto do_shiftd;
4967
    case 0x1ac: /* shrd imm */
4968
        op = 1;
4969
        shift = 1;
4970
        goto do_shiftd;
4971
    case 0x1ad: /* shrd cl */
4972
        op = 1;
4973
        shift = 0;
4974
    do_shiftd:
4975
        ot = dflag + OT_WORD;
4976
        modrm = ldub_code(s->pc++);
4977
        mod = (modrm >> 6) & 3;
4978
        rm = (modrm & 7) | REX_B(s);
4979
        reg = ((modrm >> 3) & 7) | rex_r;
4980
        if (mod != 3) {
4981
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4982
            opreg = OR_TMP0;
4983
        } else {
4984
            opreg = rm;
4985
        }
4986
        gen_op_mov_TN_reg(ot, 1, reg);
4987

    
4988
        if (shift) {
4989
            val = ldub_code(s->pc++);
4990
            tcg_gen_movi_tl(cpu_T3, val);
4991
        } else {
4992
            tcg_gen_ld_tl(cpu_T3, cpu_env, offsetof(CPUState, regs[R_ECX]));
4993
        }
4994
        gen_shiftd_rm_T1_T3(s, ot, opreg, op);
4995
        break;
4996

    
4997
        /************************/
4998
        /* floats */
4999
    case 0xd8 ... 0xdf:
5000
        if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
5001
            /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5002
            /* XXX: what to do if illegal op ? */
5003
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5004
            break;
5005
        }
5006
        modrm = ldub_code(s->pc++);
5007
        mod = (modrm >> 6) & 3;
5008
        rm = modrm & 7;
5009
        op = ((b & 7) << 3) | ((modrm >> 3) & 7);
5010
        if (mod != 3) {
5011
            /* memory op */
5012
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5013
            switch(op) {
5014
            case 0x00 ... 0x07: /* fxxxs */
5015
            case 0x10 ... 0x17: /* fixxxl */
5016
            case 0x20 ... 0x27: /* fxxxl */
5017
            case 0x30 ... 0x37: /* fixxx */
5018
                {
5019
                    int op1;
5020
                    op1 = op & 7;
5021

    
5022
                    switch(op >> 4) {
5023
                    case 0:
5024
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5025
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5026
                        tcg_gen_helper_0_1(helper_flds_FT0, cpu_tmp2_i32);
5027
                        break;
5028
                    case 1:
5029
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5030
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5031
                        tcg_gen_helper_0_1(helper_fildl_FT0, cpu_tmp2_i32);
5032
                        break;
5033
                    case 2:
5034
                        tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
5035
                                          (s->mem_index >> 2) - 1);
5036
                        tcg_gen_helper_0_1(helper_fldl_FT0, cpu_tmp1_i64);
5037
                        break;
5038
                    case 3:
5039
                    default:
5040
                        gen_op_lds_T0_A0(OT_WORD + s->mem_index);
5041
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5042
                        tcg_gen_helper_0_1(helper_fildl_FT0, cpu_tmp2_i32);
5043
                        break;
5044
                    }
5045

    
5046
                    tcg_gen_helper_0_0(helper_fp_arith_ST0_FT0[op1]);
5047
                    if (op1 == 3) {
5048
                        /* fcomp needs pop */
5049
                        tcg_gen_helper_0_0(helper_fpop);
5050
                    }
5051
                }
5052
                break;
5053
            case 0x08: /* flds */
5054
            case 0x0a: /* fsts */
5055
            case 0x0b: /* fstps */
5056
            case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5057
            case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5058
            case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5059
                switch(op & 7) {
5060
                case 0:
5061
                    switch(op >> 4) {
5062
                    case 0:
5063
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5064
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5065
                        tcg_gen_helper_0_1(helper_flds_ST0, cpu_tmp2_i32);
5066
                        break;
5067
                    case 1:
5068
                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5069
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5070
                        tcg_gen_helper_0_1(helper_fildl_ST0, cpu_tmp2_i32);
5071
                        break;
5072
                    case 2:
5073
                        tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
5074
                                          (s->mem_index >> 2) - 1);
5075
                        tcg_gen_helper_0_1(helper_fldl_ST0, cpu_tmp1_i64);
5076
                        break;
5077
                    case 3:
5078
                    default:
5079
                        gen_op_lds_T0_A0(OT_WORD + s->mem_index);
5080
                        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5081
                        tcg_gen_helper_0_1(helper_fildl_ST0, cpu_tmp2_i32);
5082
                        break;
5083
                    }
5084
                    break;
5085
                case 1:
5086
                    /* XXX: the corresponding CPUID bit must be tested ! */
5087
                    switch(op >> 4) {
5088
                    case 1:
5089
                        tcg_gen_helper_1_0(helper_fisttl_ST0, cpu_tmp2_i32);
5090
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5091
                        gen_op_st_T0_A0(OT_LONG + s->mem_index);
5092
                        break;
5093
                    case 2:
5094
                        tcg_gen_helper_1_0(helper_fisttll_ST0, cpu_tmp1_i64);
5095
                        tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
5096
                                          (s->mem_index >> 2) - 1);
5097
                        break;
5098
                    case 3:
5099
                    default:
5100
                        tcg_gen_helper_1_0(helper_fistt_ST0, cpu_tmp2_i32);
5101
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5102
                        gen_op_st_T0_A0(OT_WORD + s->mem_index);
5103
                        break;
5104
                    }
5105
                    tcg_gen_helper_0_0(helper_fpop);
5106
                    break;
5107
                default:
5108
                    switch(op >> 4) {
5109
                    case 0:
5110
                        tcg_gen_helper_1_0(helper_fsts_ST0, cpu_tmp2_i32);
5111
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5112
                        gen_op_st_T0_A0(OT_LONG + s->mem_index);
5113
                        break;
5114
                    case 1:
5115
                        tcg_gen_helper_1_0(helper_fistl_ST0, cpu_tmp2_i32);
5116
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5117
                        gen_op_st_T0_A0(OT_LONG + s->mem_index);
5118
                        break;
5119
                    case 2:
5120
                        tcg_gen_helper_1_0(helper_fstl_ST0, cpu_tmp1_i64);
5121
                        tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
5122
                                          (s->mem_index >> 2) - 1);
5123
                        break;
5124
                    case 3:
5125
                    default:
5126
                        tcg_gen_helper_1_0(helper_fist_ST0, cpu_tmp2_i32);
5127
                        tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5128
                        gen_op_st_T0_A0(OT_WORD + s->mem_index);
5129
                        break;
5130
                    }
5131
                    if ((op & 7) == 3)
5132
                        tcg_gen_helper_0_0(helper_fpop);
5133
                    break;
5134
                }
5135
                break;
5136
            case 0x0c: /* fldenv mem */
5137
                if (s->cc_op != CC_OP_DYNAMIC)
5138
                    gen_op_set_cc_op(s->cc_op);
5139
                gen_jmp_im(pc_start - s->cs_base);
5140
                tcg_gen_helper_0_2(helper_fldenv, 
5141
                                   cpu_A0, tcg_const_i32(s->dflag));
5142
                break;
5143
            case 0x0d: /* fldcw mem */
5144
                gen_op_ld_T0_A0(OT_WORD + s->mem_index);
5145
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5146
                tcg_gen_helper_0_1(helper_fldcw, cpu_tmp2_i32);
5147
                break;
5148
            case 0x0e: /* fnstenv mem */
5149
                if (s->cc_op != CC_OP_DYNAMIC)
5150
                    gen_op_set_cc_op(s->cc_op);
5151
                gen_jmp_im(pc_start - s->cs_base);
5152
                tcg_gen_helper_0_2(helper_fstenv,
5153
                                   cpu_A0, tcg_const_i32(s->dflag));
5154
                break;
5155
            case 0x0f: /* fnstcw mem */
5156
                tcg_gen_helper_1_0(helper_fnstcw, cpu_tmp2_i32);
5157
                tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5158
                gen_op_st_T0_A0(OT_WORD + s->mem_index);
5159
                break;
5160
            case 0x1d: /* fldt mem */
5161
                if (s->cc_op != CC_OP_DYNAMIC)
5162
                    gen_op_set_cc_op(s->cc_op);
5163
                gen_jmp_im(pc_start - s->cs_base);
5164
                tcg_gen_helper_0_1(helper_fldt_ST0, cpu_A0);
5165
                break;
5166
            case 0x1f: /* fstpt mem */
5167
                if (s->cc_op != CC_OP_DYNAMIC)
5168
                    gen_op_set_cc_op(s->cc_op);
5169
                gen_jmp_im(pc_start - s->cs_base);
5170
                tcg_gen_helper_0_1(helper_fstt_ST0, cpu_A0);
5171
                tcg_gen_helper_0_0(helper_fpop);
5172
                break;
5173
            case 0x2c: /* frstor mem */
5174
                if (s->cc_op != CC_OP_DYNAMIC)
5175
                    gen_op_set_cc_op(s->cc_op);
5176
                gen_jmp_im(pc_start - s->cs_base);
5177
                tcg_gen_helper_0_2(helper_frstor,
5178
                                   cpu_A0, tcg_const_i32(s->dflag));
5179
                break;
5180
            case 0x2e: /* fnsave mem */
5181
                if (s->cc_op != CC_OP_DYNAMIC)
5182
                    gen_op_set_cc_op(s->cc_op);
5183
                gen_jmp_im(pc_start - s->cs_base);
5184
                tcg_gen_helper_0_2(helper_fsave,
5185
                                   cpu_A0, tcg_const_i32(s->dflag));
5186
                break;
5187
            case 0x2f: /* fnstsw mem */
5188
                tcg_gen_helper_1_0(helper_fnstsw, cpu_tmp2_i32);
5189
                tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5190
                gen_op_st_T0_A0(OT_WORD + s->mem_index);
5191
                break;
5192
            case 0x3c: /* fbld */
5193
                if (s->cc_op != CC_OP_DYNAMIC)
5194
                    gen_op_set_cc_op(s->cc_op);
5195
                gen_jmp_im(pc_start - s->cs_base);
5196
                tcg_gen_helper_0_1(helper_fbld_ST0, cpu_A0);
5197
                break;
5198
            case 0x3e: /* fbstp */
5199
                if (s->cc_op != CC_OP_DYNAMIC)
5200
                    gen_op_set_cc_op(s->cc_op);
5201
                gen_jmp_im(pc_start - s->cs_base);
5202
                tcg_gen_helper_0_1(helper_fbst_ST0, cpu_A0);
5203
                tcg_gen_helper_0_0(helper_fpop);
5204
                break;
5205
            case 0x3d: /* fildll */
5206
                tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
5207
                                  (s->mem_index >> 2) - 1);
5208
                tcg_gen_helper_0_1(helper_fildll_ST0, cpu_tmp1_i64);
5209
                break;
5210
            case 0x3f: /* fistpll */
5211
                tcg_gen_helper_1_0(helper_fistll_ST0, cpu_tmp1_i64);
5212
                tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
5213
                                  (s->mem_index >> 2) - 1);
5214
                tcg_gen_helper_0_0(helper_fpop);
5215
                break;
5216
            default:
5217
                goto illegal_op;
5218
            }
5219
        } else {
5220
            /* register float ops */
5221
            opreg = rm;
5222

    
5223
            switch(op) {
5224
            case 0x08: /* fld sti */
5225
                tcg_gen_helper_0_0(helper_fpush);
5226
                tcg_gen_helper_0_1(helper_fmov_ST0_STN, tcg_const_i32((opreg + 1) & 7));
5227
                break;
5228
            case 0x09: /* fxchg sti */
5229
            case 0x29: /* fxchg4 sti, undocumented op */
5230
            case 0x39: /* fxchg7 sti, undocumented op */
5231
                tcg_gen_helper_0_1(helper_fxchg_ST0_STN, tcg_const_i32(opreg));
5232
                break;
5233
            case 0x0a: /* grp d9/2 */
5234
                switch(rm) {
5235
                case 0: /* fnop */
5236
                    /* check exceptions (FreeBSD FPU probe) */
5237
                    if (s->cc_op != CC_OP_DYNAMIC)
5238
                        gen_op_set_cc_op(s->cc_op);
5239
                    gen_jmp_im(pc_start - s->cs_base);
5240
                    tcg_gen_helper_0_0(helper_fwait);
5241
                    break;
5242
                default:
5243
                    goto illegal_op;
5244
                }
5245
                break;
5246
            case 0x0c: /* grp d9/4 */
5247
                switch(rm) {
5248
                case 0: /* fchs */
5249
                    tcg_gen_helper_0_0(helper_fchs_ST0);
5250
                    break;
5251
                case 1: /* fabs */
5252
                    tcg_gen_helper_0_0(helper_fabs_ST0);
5253
                    break;
5254
                case 4: /* ftst */
5255
                    tcg_gen_helper_0_0(helper_fldz_FT0);
5256
                    tcg_gen_helper_0_0(helper_fcom_ST0_FT0);
5257
                    break;
5258
                case 5: /* fxam */
5259
                    tcg_gen_helper_0_0(helper_fxam_ST0);
5260
                    break;
5261
                default:
5262
                    goto illegal_op;
5263
                }
5264
                break;
5265
            case 0x0d: /* grp d9/5 */
5266
                {
5267
                    switch(rm) {
5268
                    case 0:
5269
                        tcg_gen_helper_0_0(helper_fpush);
5270
                        tcg_gen_helper_0_0(helper_fld1_ST0);
5271
                        break;
5272
                    case 1:
5273
                        tcg_gen_helper_0_0(helper_fpush);
5274
                        tcg_gen_helper_0_0(helper_fldl2t_ST0);
5275
                        break;
5276
                    case 2:
5277
                        tcg_gen_helper_0_0(helper_fpush);
5278
                        tcg_gen_helper_0_0(helper_fldl2e_ST0);
5279
                        break;
5280
                    case 3:
5281
                        tcg_gen_helper_0_0(helper_fpush);
5282
                        tcg_gen_helper_0_0(helper_fldpi_ST0);
5283
                        break;
5284
                    case 4:
5285
                        tcg_gen_helper_0_0(helper_fpush);
5286
                        tcg_gen_helper_0_0(helper_fldlg2_ST0);
5287
                        break;
5288
                    case 5:
5289
                        tcg_gen_helper_0_0(helper_fpush);
5290
                        tcg_gen_helper_0_0(helper_fldln2_ST0);
5291
                        break;
5292
                    case 6:
5293
                        tcg_gen_helper_0_0(helper_fpush);
5294
                        tcg_gen_helper_0_0(helper_fldz_ST0);
5295
                        break;
5296
                    default:
5297
                        goto illegal_op;
5298
                    }
5299
                }
5300
                break;
5301
            case 0x0e: /* grp d9/6 */
5302
                switch(rm) {
5303
                case 0: /* f2xm1 */
5304
                    tcg_gen_helper_0_0(helper_f2xm1);
5305
                    break;
5306
                case 1: /* fyl2x */
5307
                    tcg_gen_helper_0_0(helper_fyl2x);
5308
                    break;
5309
                case 2: /* fptan */
5310
                    tcg_gen_helper_0_0(helper_fptan);
5311
                    break;
5312
                case 3: /* fpatan */
5313
                    tcg_gen_helper_0_0(helper_fpatan);
5314
                    break;
5315
                case 4: /* fxtract */
5316
                    tcg_gen_helper_0_0(helper_fxtract);
5317
                    break;
5318
                case 5: /* fprem1 */
5319
                    tcg_gen_helper_0_0(helper_fprem1);
5320
                    break;
5321
                case 6: /* fdecstp */
5322
                    tcg_gen_helper_0_0(helper_fdecstp);
5323
                    break;
5324
                default:
5325
                case 7: /* fincstp */
5326
                    tcg_gen_helper_0_0(helper_fincstp);
5327
                    break;
5328
                }
5329
                break;
5330
            case 0x0f: /* grp d9/7 */
5331
                switch(rm) {
5332
                case 0: /* fprem */
5333
                    tcg_gen_helper_0_0(helper_fprem);
5334
                    break;
5335
                case 1: /* fyl2xp1 */
5336
                    tcg_gen_helper_0_0(helper_fyl2xp1);
5337
                    break;
5338
                case 2: /* fsqrt */
5339
                    tcg_gen_helper_0_0(helper_fsqrt);
5340
                    break;
5341
                case 3: /* fsincos */
5342
                    tcg_gen_helper_0_0(helper_fsincos);
5343
                    break;
5344
                case 5: /* fscale */
5345
                    tcg_gen_helper_0_0(helper_fscale);
5346
                    break;
5347
                case 4: /* frndint */
5348
                    tcg_gen_helper_0_0(helper_frndint);
5349
                    break;
5350
                case 6: /* fsin */
5351
                    tcg_gen_helper_0_0(helper_fsin);
5352
                    break;
5353
                default:
5354
                case 7: /* fcos */
5355
                    tcg_gen_helper_0_0(helper_fcos);
5356
                    break;
5357
                }
5358
                break;
5359
            case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
5360
            case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
5361
            case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
5362
                {
5363
                    int op1;
5364

    
5365
                    op1 = op & 7;
5366
                    if (op >= 0x20) {
5367
                        tcg_gen_helper_0_1(helper_fp_arith_STN_ST0[op1], tcg_const_i32(opreg));
5368
                        if (op >= 0x30)
5369
                            tcg_gen_helper_0_0(helper_fpop);
5370
                    } else {
5371
                        tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
5372
                        tcg_gen_helper_0_0(helper_fp_arith_ST0_FT0[op1]);
5373
                    }
5374
                }
5375
                break;
5376
            case 0x02: /* fcom */
5377
            case 0x22: /* fcom2, undocumented op */
5378
                tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
5379
                tcg_gen_helper_0_0(helper_fcom_ST0_FT0);
5380
                break;
5381
            case 0x03: /* fcomp */
5382
            case 0x23: /* fcomp3, undocumented op */
5383
            case 0x32: /* fcomp5, undocumented op */
5384
                tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
5385
                tcg_gen_helper_0_0(helper_fcom_ST0_FT0);
5386
                tcg_gen_helper_0_0(helper_fpop);
5387
                break;
5388
            case 0x15: /* da/5 */
5389
                switch(rm) {
5390
                case 1: /* fucompp */
5391
                    tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(1));
5392
                    tcg_gen_helper_0_0(helper_fucom_ST0_FT0);
5393
                    tcg_gen_helper_0_0(helper_fpop);
5394
                    tcg_gen_helper_0_0(helper_fpop);
5395
                    break;
5396
                default:
5397
                    goto illegal_op;
5398
                }
5399
                break;
5400
            case 0x1c:
5401
                switch(rm) {
5402
                case 0: /* feni (287 only, just do nop here) */
5403
                    break;
5404
                case 1: /* fdisi (287 only, just do nop here) */
5405
                    break;
5406
                case 2: /* fclex */
5407
                    tcg_gen_helper_0_0(helper_fclex);
5408
                    break;
5409
                case 3: /* fninit */
5410
                    tcg_gen_helper_0_0(helper_fninit);
5411
                    break;
5412
                case 4: /* fsetpm (287 only, just do nop here) */
5413
                    break;
5414
                default:
5415
                    goto illegal_op;
5416
                }
5417
                break;
5418
            case 0x1d: /* fucomi */
5419
                if (s->cc_op != CC_OP_DYNAMIC)
5420
                    gen_op_set_cc_op(s->cc_op);
5421
                tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
5422
                tcg_gen_helper_0_0(helper_fucomi_ST0_FT0);
5423
                s->cc_op = CC_OP_EFLAGS;
5424
                break;
5425
            case 0x1e: /* fcomi */
5426
                if (s->cc_op != CC_OP_DYNAMIC)
5427
                    gen_op_set_cc_op(s->cc_op);
5428
                tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
5429
                tcg_gen_helper_0_0(helper_fcomi_ST0_FT0);
5430
                s->cc_op = CC_OP_EFLAGS;
5431
                break;
5432
            case 0x28: /* ffree sti */
5433
                tcg_gen_helper_0_1(helper_ffree_STN, tcg_const_i32(opreg));
5434
                break;
5435
            case 0x2a: /* fst sti */
5436
                tcg_gen_helper_0_1(helper_fmov_STN_ST0, tcg_const_i32(opreg));
5437
                break;
5438
            case 0x2b: /* fstp sti */
5439
            case 0x0b: /* fstp1 sti, undocumented op */
5440
            case 0x3a: /* fstp8 sti, undocumented op */
5441
            case 0x3b: /* fstp9 sti, undocumented op */
5442
                tcg_gen_helper_0_1(helper_fmov_STN_ST0, tcg_const_i32(opreg));
5443
                tcg_gen_helper_0_0(helper_fpop);
5444
                break;
5445
            case 0x2c: /* fucom st(i) */
5446
                tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
5447
                tcg_gen_helper_0_0(helper_fucom_ST0_FT0);
5448
                break;
5449
            case 0x2d: /* fucomp st(i) */
5450
                tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
5451
                tcg_gen_helper_0_0(helper_fucom_ST0_FT0);
5452
                tcg_gen_helper_0_0(helper_fpop);
5453
                break;
5454
            case 0x33: /* de/3 */
5455
                switch(rm) {
5456
                case 1: /* fcompp */
5457
                    tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(1));
5458
                    tcg_gen_helper_0_0(helper_fcom_ST0_FT0);
5459
                    tcg_gen_helper_0_0(helper_fpop);
5460
                    tcg_gen_helper_0_0(helper_fpop);
5461
                    break;
5462
                default:
5463
                    goto illegal_op;
5464
                }
5465
                break;
5466
            case 0x38: /* ffreep sti, undocumented op */
5467
                tcg_gen_helper_0_1(helper_ffree_STN, tcg_const_i32(opreg));
5468
                tcg_gen_helper_0_0(helper_fpop);
5469
                break;
5470
            case 0x3c: /* df/4 */
5471
                switch(rm) {
5472
                case 0:
5473
                    tcg_gen_helper_1_0(helper_fnstsw, cpu_tmp2_i32);
5474
                    tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5475
                    gen_op_mov_reg_T0(OT_WORD, R_EAX);
5476
                    break;
5477
                default:
5478
                    goto illegal_op;
5479
                }
5480
                break;
5481
            case 0x3d: /* fucomip */
5482
                if (s->cc_op != CC_OP_DYNAMIC)
5483
                    gen_op_set_cc_op(s->cc_op);
5484
                tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
5485
                tcg_gen_helper_0_0(helper_fucomi_ST0_FT0);
5486
                tcg_gen_helper_0_0(helper_fpop);
5487
                s->cc_op = CC_OP_EFLAGS;
5488
                break;
5489
            case 0x3e: /* fcomip */
5490
                if (s->cc_op != CC_OP_DYNAMIC)
5491
                    gen_op_set_cc_op(s->cc_op);
5492
                tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
5493
                tcg_gen_helper_0_0(helper_fcomi_ST0_FT0);
5494
                tcg_gen_helper_0_0(helper_fpop);
5495
                s->cc_op = CC_OP_EFLAGS;
5496
                break;
5497
            case 0x10 ... 0x13: /* fcmovxx */
5498
            case 0x18 ... 0x1b:
5499
                {
5500
                    int op1, l1;
5501
                    const static uint8_t fcmov_cc[8] = {
5502
                        (JCC_B << 1),
5503
                        (JCC_Z << 1),
5504
                        (JCC_BE << 1),
5505
                        (JCC_P << 1),
5506
                    };
5507
                    op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
5508
                    l1 = gen_new_label();
5509
                    gen_jcc1(s, s->cc_op, op1, l1);
5510
                    tcg_gen_helper_0_1(helper_fmov_ST0_STN, tcg_const_i32(opreg));
5511
                    gen_set_label(l1);
5512
                }
5513
                break;
5514
            default:
5515
                goto illegal_op;
5516
            }
5517
        }
5518
        break;
5519
        /************************/
5520
        /* string ops */
5521

    
5522
    case 0xa4: /* movsS */
5523
    case 0xa5:
5524
        if ((b & 1) == 0)
5525
            ot = OT_BYTE;
5526
        else
5527
            ot = dflag + OT_WORD;
5528

    
5529
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5530
            gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5531
        } else {
5532
            gen_movs(s, ot);
5533
        }
5534
        break;
5535

    
5536
    case 0xaa: /* stosS */
5537
    case 0xab:
5538
        if ((b & 1) == 0)
5539
            ot = OT_BYTE;
5540
        else
5541
            ot = dflag + OT_WORD;
5542

    
5543
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5544
            gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5545
        } else {
5546
            gen_stos(s, ot);
5547
        }
5548
        break;
5549
    case 0xac: /* lodsS */
5550
    case 0xad:
5551
        if ((b & 1) == 0)
5552
            ot = OT_BYTE;
5553
        else
5554
            ot = dflag + OT_WORD;
5555
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5556
            gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5557
        } else {
5558
            gen_lods(s, ot);
5559
        }
5560
        break;
5561
    case 0xae: /* scasS */
5562
    case 0xaf:
5563
        if ((b & 1) == 0)
5564
            ot = OT_BYTE;
5565
        else
5566
            ot = dflag + OT_WORD;
5567
        if (prefixes & PREFIX_REPNZ) {
5568
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
5569
        } else if (prefixes & PREFIX_REPZ) {
5570
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
5571
        } else {
5572
            gen_scas(s, ot);
5573
            s->cc_op = CC_OP_SUBB + ot;
5574
        }
5575
        break;
5576

    
5577
    case 0xa6: /* cmpsS */
5578
    case 0xa7:
5579
        if ((b & 1) == 0)
5580
            ot = OT_BYTE;
5581
        else
5582
            ot = dflag + OT_WORD;
5583
        if (prefixes & PREFIX_REPNZ) {
5584
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
5585
        } else if (prefixes & PREFIX_REPZ) {
5586
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
5587
        } else {
5588
            gen_cmps(s, ot);
5589
            s->cc_op = CC_OP_SUBB + ot;
5590
        }
5591
        break;
5592
    case 0x6c: /* insS */
5593
    case 0x6d:
5594
        if ((b & 1) == 0)
5595
            ot = OT_BYTE;
5596
        else
5597
            ot = dflag ? OT_LONG : OT_WORD;
5598
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5599
        gen_op_andl_T0_ffff();
5600
        gen_check_io(s, ot, pc_start - s->cs_base, 
5601
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
5602
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5603
            gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5604
        } else {
5605
            gen_ins(s, ot);
5606
        }
5607
        break;
5608
    case 0x6e: /* outsS */
5609
    case 0x6f:
5610
        if ((b & 1) == 0)
5611
            ot = OT_BYTE;
5612
        else
5613
            ot = dflag ? OT_LONG : OT_WORD;
5614
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5615
        gen_op_andl_T0_ffff();
5616
        gen_check_io(s, ot, pc_start - s->cs_base,
5617
                     svm_is_rep(prefixes) | 4);
5618
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5619
            gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5620
        } else {
5621
            gen_outs(s, ot);
5622
        }
5623
        break;
5624

    
5625
        /************************/
5626
        /* port I/O */
5627

    
5628
    case 0xe4:
5629
    case 0xe5:
5630
        if ((b & 1) == 0)
5631
            ot = OT_BYTE;
5632
        else
5633
            ot = dflag ? OT_LONG : OT_WORD;
5634
        val = ldub_code(s->pc++);
5635
        gen_op_movl_T0_im(val);
5636
        gen_check_io(s, ot, pc_start - s->cs_base,
5637
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
5638
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5639
        tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[1], cpu_tmp2_i32);
5640
        gen_op_mov_reg_T1(ot, R_EAX);
5641
        break;
5642
    case 0xe6:
5643
    case 0xe7:
5644
        if ((b & 1) == 0)
5645
            ot = OT_BYTE;
5646
        else
5647
            ot = dflag ? OT_LONG : OT_WORD;
5648
        val = ldub_code(s->pc++);
5649
        gen_op_movl_T0_im(val);
5650
        gen_check_io(s, ot, pc_start - s->cs_base,
5651
                     svm_is_rep(prefixes));
5652
        gen_op_mov_TN_reg(ot, 1, R_EAX);
5653

    
5654
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5655
        tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
5656
        tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
5657
        tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2_i32, cpu_tmp3_i32);
5658
        break;
5659
    case 0xec:
5660
    case 0xed:
5661
        if ((b & 1) == 0)
5662
            ot = OT_BYTE;
5663
        else
5664
            ot = dflag ? OT_LONG : OT_WORD;
5665
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5666
        gen_op_andl_T0_ffff();
5667
        gen_check_io(s, ot, pc_start - s->cs_base,
5668
                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
5669
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5670
        tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[1], cpu_tmp2_i32);
5671
        gen_op_mov_reg_T1(ot, R_EAX);
5672
        break;
5673
    case 0xee:
5674
    case 0xef:
5675
        if ((b & 1) == 0)
5676
            ot = OT_BYTE;
5677
        else
5678
            ot = dflag ? OT_LONG : OT_WORD;
5679
        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5680
        gen_op_andl_T0_ffff();
5681
        gen_check_io(s, ot, pc_start - s->cs_base,
5682
                     svm_is_rep(prefixes));
5683
        gen_op_mov_TN_reg(ot, 1, R_EAX);
5684

    
5685
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5686
        tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
5687
        tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
5688
        tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2_i32, cpu_tmp3_i32);
5689
        break;
5690

    
5691
        /************************/
5692
        /* control */
5693
    case 0xc2: /* ret im */
5694
        val = ldsw_code(s->pc);
5695
        s->pc += 2;
5696
        gen_pop_T0(s);
5697
        if (CODE64(s) && s->dflag)
5698
            s->dflag = 2;
5699
        gen_stack_update(s, val + (2 << s->dflag));
5700
        if (s->dflag == 0)
5701
            gen_op_andl_T0_ffff();
5702
        gen_op_jmp_T0();
5703
        gen_eob(s);
5704
        break;
5705
    case 0xc3: /* ret */
5706
        gen_pop_T0(s);
5707
        gen_pop_update(s);
5708
        if (s->dflag == 0)
5709
            gen_op_andl_T0_ffff();
5710
        gen_op_jmp_T0();
5711
        gen_eob(s);
5712
        break;
5713
    case 0xca: /* lret im */
5714
        val = ldsw_code(s->pc);
5715
        s->pc += 2;
5716
    do_lret:
5717
        if (s->pe && !s->vm86) {
5718
            if (s->cc_op != CC_OP_DYNAMIC)
5719
                gen_op_set_cc_op(s->cc_op);
5720
            gen_jmp_im(pc_start - s->cs_base);
5721
            tcg_gen_helper_0_2(helper_lret_protected,
5722
                               tcg_const_i32(s->dflag), 
5723
                               tcg_const_i32(val));
5724
        } else {
5725
            gen_stack_A0(s);
5726
            /* pop offset */
5727
            gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
5728
            if (s->dflag == 0)
5729
                gen_op_andl_T0_ffff();
5730
            /* NOTE: keeping EIP updated is not a problem in case of
5731
               exception */
5732
            gen_op_jmp_T0();
5733
            /* pop selector */
5734
            gen_op_addl_A0_im(2 << s->dflag);
5735
            gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
5736
            gen_op_movl_seg_T0_vm(R_CS);
5737
            /* add stack offset */
5738
            gen_stack_update(s, val + (4 << s->dflag));
5739
        }
5740
        gen_eob(s);
5741
        break;
5742
    case 0xcb: /* lret */
5743
        val = 0;
5744
        goto do_lret;
5745
    case 0xcf: /* iret */
5746
        if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET))
5747
            break;
5748
        if (!s->pe) {
5749
            /* real mode */
5750
            tcg_gen_helper_0_1(helper_iret_real, tcg_const_i32(s->dflag));
5751
            s->cc_op = CC_OP_EFLAGS;
5752
        } else if (s->vm86) {
5753
            if (s->iopl != 3) {
5754
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5755
            } else {
5756
                tcg_gen_helper_0_1(helper_iret_real, tcg_const_i32(s->dflag));
5757
                s->cc_op = CC_OP_EFLAGS;
5758
            }
5759
        } else {
5760
            if (s->cc_op != CC_OP_DYNAMIC)
5761
                gen_op_set_cc_op(s->cc_op);
5762
            gen_jmp_im(pc_start - s->cs_base);
5763
            tcg_gen_helper_0_2(helper_iret_protected,
5764
                               tcg_const_i32(s->dflag), 
5765
                               tcg_const_i32(s->pc - s->cs_base));
5766
            s->cc_op = CC_OP_EFLAGS;
5767
        }
5768
        gen_eob(s);
5769
        break;
5770
    case 0xe8: /* call im */
5771
        {
5772
            if (dflag)
5773
                tval = (int32_t)insn_get(s, OT_LONG);
5774
            else
5775
                tval = (int16_t)insn_get(s, OT_WORD);
5776
            next_eip = s->pc - s->cs_base;
5777
            tval += next_eip;
5778
            if (s->dflag == 0)
5779
                tval &= 0xffff;
5780
            gen_movtl_T0_im(next_eip);
5781
            gen_push_T0(s);
5782
            gen_jmp(s, tval);
5783
        }
5784
        break;
5785
    case 0x9a: /* lcall im */
5786
        {
5787
            unsigned int selector, offset;
5788

    
5789
            if (CODE64(s))
5790
                goto illegal_op;
5791
            ot = dflag ? OT_LONG : OT_WORD;
5792
            offset = insn_get(s, ot);
5793
            selector = insn_get(s, OT_WORD);
5794

    
5795
            gen_op_movl_T0_im(selector);
5796
            gen_op_movl_T1_imu(offset);
5797
        }
5798
        goto do_lcall;
5799
    case 0xe9: /* jmp im */
5800
        if (dflag)
5801
            tval = (int32_t)insn_get(s, OT_LONG);
5802
        else
5803
            tval = (int16_t)insn_get(s, OT_WORD);
5804
        tval += s->pc - s->cs_base;
5805
        if (s->dflag == 0)
5806
            tval &= 0xffff;
5807
        gen_jmp(s, tval);
5808
        break;
5809
    case 0xea: /* ljmp im */
5810
        {
5811
            unsigned int selector, offset;
5812

    
5813
            if (CODE64(s))
5814
                goto illegal_op;
5815
            ot = dflag ? OT_LONG : OT_WORD;
5816
            offset = insn_get(s, ot);
5817
            selector = insn_get(s, OT_WORD);
5818

    
5819
            gen_op_movl_T0_im(selector);
5820
            gen_op_movl_T1_imu(offset);
5821
        }
5822
        goto do_ljmp;
5823
    case 0xeb: /* jmp Jb */
5824
        tval = (int8_t)insn_get(s, OT_BYTE);
5825
        tval += s->pc - s->cs_base;
5826
        if (s->dflag == 0)
5827
            tval &= 0xffff;
5828
        gen_jmp(s, tval);
5829
        break;
5830
    case 0x70 ... 0x7f: /* jcc Jb */
5831
        tval = (int8_t)insn_get(s, OT_BYTE);
5832
        goto do_jcc;
5833
    case 0x180 ... 0x18f: /* jcc Jv */
5834
        if (dflag) {
5835
            tval = (int32_t)insn_get(s, OT_LONG);
5836
        } else {
5837
            tval = (int16_t)insn_get(s, OT_WORD);
5838
        }
5839
    do_jcc:
5840
        next_eip = s->pc - s->cs_base;
5841
        tval += next_eip;
5842
        if (s->dflag == 0)
5843
            tval &= 0xffff;
5844
        gen_jcc(s, b, tval, next_eip);
5845
        break;
5846

    
5847
    case 0x190 ... 0x19f: /* setcc Gv */
5848
        modrm = ldub_code(s->pc++);
5849
        gen_setcc(s, b);
5850
        gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
5851
        break;
5852
    case 0x140 ... 0x14f: /* cmov Gv, Ev */
5853
        {
5854
            int l1;
5855
            TCGv t0;
5856

    
5857
            ot = dflag + OT_WORD;
5858
            modrm = ldub_code(s->pc++);
5859
            reg = ((modrm >> 3) & 7) | rex_r;
5860
            mod = (modrm >> 6) & 3;
5861
            t0 = tcg_temp_local_new(TCG_TYPE_TL);
5862
            if (mod != 3) {
5863
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5864
                gen_op_ld_v(ot + s->mem_index, t0, cpu_A0);
5865
            } else {
5866
                rm = (modrm & 7) | REX_B(s);
5867
                gen_op_mov_v_reg(ot, t0, rm);
5868
            }
5869
#ifdef TARGET_X86_64
5870
            if (ot == OT_LONG) {
5871
                /* XXX: specific Intel behaviour ? */
5872
                l1 = gen_new_label();
5873
                gen_jcc1(s, s->cc_op, b ^ 1, l1);
5874
                tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
5875
                gen_set_label(l1);
5876
                tcg_gen_movi_tl(cpu_tmp0, 0);
5877
                tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_LH_OFFSET);
5878
            } else
5879
#endif
5880
            {
5881
                l1 = gen_new_label();
5882
                gen_jcc1(s, s->cc_op, b ^ 1, l1);
5883
                gen_op_mov_reg_v(ot, reg, t0);
5884
                gen_set_label(l1);
5885
            }
5886
            tcg_temp_free(t0);
5887
        }
5888
        break;
5889

    
5890
        /************************/
5891
        /* flags */
5892
    case 0x9c: /* pushf */
5893
        if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF))
5894
            break;
5895
        if (s->vm86 && s->iopl != 3) {
5896
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5897
        } else {
5898
            if (s->cc_op != CC_OP_DYNAMIC)
5899
                gen_op_set_cc_op(s->cc_op);
5900
            tcg_gen_helper_1_0(helper_read_eflags, cpu_T[0]);
5901
            gen_push_T0(s);
5902
        }
5903
        break;
5904
    case 0x9d: /* popf */
5905
        if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF))
5906
            break;
5907
        if (s->vm86 && s->iopl != 3) {
5908
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5909
        } else {
5910
            gen_pop_T0(s);
5911
            if (s->cpl == 0) {
5912
                if (s->dflag) {
5913
                    tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
5914
                                       tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK)));
5915
                } else {
5916
                    tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
5917
                                       tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff));
5918
                }
5919
            } else {
5920
                if (s->cpl <= s->iopl) {
5921
                    if (s->dflag) {
5922
                        tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
5923
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK)));
5924
                    } else {
5925
                        tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
5926
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff));
5927
                    }
5928
                } else {
5929
                    if (s->dflag) {
5930
                        tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
5931
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK)));
5932
                    } else {
5933
                        tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
5934
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff));
5935
                    }
5936
                }
5937
            }
5938
            gen_pop_update(s);
5939
            s->cc_op = CC_OP_EFLAGS;
5940
            /* abort translation because TF flag may change */
5941
            gen_jmp_im(s->pc - s->cs_base);
5942
            gen_eob(s);
5943
        }
5944
        break;
5945
    case 0x9e: /* sahf */
5946
        if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
5947
            goto illegal_op;
5948
        gen_op_mov_TN_reg(OT_BYTE, 0, R_AH);
5949
        if (s->cc_op != CC_OP_DYNAMIC)
5950
            gen_op_set_cc_op(s->cc_op);
5951
        gen_compute_eflags(cpu_cc_src);
5952
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
5953
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], CC_S | CC_Z | CC_A | CC_P | CC_C);
5954
        tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T[0]);
5955
        s->cc_op = CC_OP_EFLAGS;
5956
        break;
5957
    case 0x9f: /* lahf */
5958
        if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
5959
            goto illegal_op;
5960
        if (s->cc_op != CC_OP_DYNAMIC)
5961
            gen_op_set_cc_op(s->cc_op);
5962
        gen_compute_eflags(cpu_T[0]);
5963
        /* Note: gen_compute_eflags() only gives the condition codes */
5964
        tcg_gen_ori_tl(cpu_T[0], cpu_T[0], 0x02);
5965
        gen_op_mov_reg_T0(OT_BYTE, R_AH);
5966
        break;
5967
    case 0xf5: /* cmc */
5968
        if (s->cc_op != CC_OP_DYNAMIC)
5969
            gen_op_set_cc_op(s->cc_op);
5970
        gen_compute_eflags(cpu_cc_src);
5971
        tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
5972
        s->cc_op = CC_OP_EFLAGS;
5973
        break;
5974
    case 0xf8: /* clc */
5975
        if (s->cc_op != CC_OP_DYNAMIC)
5976
            gen_op_set_cc_op(s->cc_op);
5977
        gen_compute_eflags(cpu_cc_src);
5978
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
5979
        s->cc_op = CC_OP_EFLAGS;
5980
        break;
5981
    case 0xf9: /* stc */
5982
        if (s->cc_op != CC_OP_DYNAMIC)
5983
            gen_op_set_cc_op(s->cc_op);
5984
        gen_compute_eflags(cpu_cc_src);
5985
        tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
5986
        s->cc_op = CC_OP_EFLAGS;
5987
        break;
5988
    case 0xfc: /* cld */
5989
        tcg_gen_movi_i32(cpu_tmp2_i32, 1);
5990
        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUState, df));
5991
        break;
5992
    case 0xfd: /* std */
5993
        tcg_gen_movi_i32(cpu_tmp2_i32, -1);
5994
        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUState, df));
5995
        break;
5996

    
5997
        /************************/
5998
        /* bit operations */
5999
    case 0x1ba: /* bt/bts/btr/btc Gv, im */
6000
        ot = dflag + OT_WORD;
6001
        modrm = ldub_code(s->pc++);
6002
        op = (modrm >> 3) & 7;
6003
        mod = (modrm >> 6) & 3;
6004
        rm = (modrm & 7) | REX_B(s);
6005
        if (mod != 3) {
6006
            s->rip_offset = 1;
6007
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6008
            gen_op_ld_T0_A0(ot + s->mem_index);
6009
        } else {
6010
            gen_op_mov_TN_reg(ot, 0, rm);
6011
        }
6012
        /* load shift */
6013
        val = ldub_code(s->pc++);
6014
        gen_op_movl_T1_im(val);
6015
        if (op < 4)
6016
            goto illegal_op;
6017
        op -= 4;
6018
        goto bt_op;
6019
    case 0x1a3: /* bt Gv, Ev */
6020
        op = 0;
6021
        goto do_btx;
6022
    case 0x1ab: /* bts */
6023
        op = 1;
6024
        goto do_btx;
6025
    case 0x1b3: /* btr */
6026
        op = 2;
6027
        goto do_btx;
6028
    case 0x1bb: /* btc */
6029
        op = 3;
6030
    do_btx:
6031
        ot = dflag + OT_WORD;
6032
        modrm = ldub_code(s->pc++);
6033
        reg = ((modrm >> 3) & 7) | rex_r;
6034
        mod = (modrm >> 6) & 3;
6035
        rm = (modrm & 7) | REX_B(s);
6036
        gen_op_mov_TN_reg(OT_LONG, 1, reg);
6037
        if (mod != 3) {
6038
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6039
            /* specific case: we need to add a displacement */
6040
            gen_exts(ot, cpu_T[1]);
6041
            tcg_gen_sari_tl(cpu_tmp0, cpu_T[1], 3 + ot);
6042
            tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
6043
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
6044
            gen_op_ld_T0_A0(ot + s->mem_index);
6045
        } else {
6046
            gen_op_mov_TN_reg(ot, 0, rm);
6047
        }
6048
    bt_op:
6049
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], (1 << (3 + ot)) - 1);
6050
        switch(op) {
6051
        case 0:
6052
            tcg_gen_shr_tl(cpu_cc_src, cpu_T[0], cpu_T[1]);
6053
            tcg_gen_movi_tl(cpu_cc_dst, 0);
6054
            break;
6055
        case 1:
6056
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6057
            tcg_gen_movi_tl(cpu_tmp0, 1);
6058
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6059
            tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6060
            break;
6061
        case 2:
6062
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6063
            tcg_gen_movi_tl(cpu_tmp0, 1);
6064
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6065
            tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
6066
            tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6067
            break;
6068
        default:
6069
        case 3:
6070
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6071
            tcg_gen_movi_tl(cpu_tmp0, 1);
6072
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6073
            tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6074
            break;
6075
        }
6076
        s->cc_op = CC_OP_SARB + ot;
6077
        if (op != 0) {
6078
            if (mod != 3)
6079
                gen_op_st_T0_A0(ot + s->mem_index);
6080
            else
6081
                gen_op_mov_reg_T0(ot, rm);
6082
            tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
6083
            tcg_gen_movi_tl(cpu_cc_dst, 0);
6084
        }
6085
        break;
6086
    case 0x1bc: /* bsf */
6087
    case 0x1bd: /* bsr */
6088
        {
6089
            int label1;
6090
            TCGv t0;
6091

    
6092
            ot = dflag + OT_WORD;
6093
            modrm = ldub_code(s->pc++);
6094
            reg = ((modrm >> 3) & 7) | rex_r;
6095
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
6096
            gen_extu(ot, cpu_T[0]);
6097
            label1 = gen_new_label();
6098
            tcg_gen_movi_tl(cpu_cc_dst, 0);
6099
            t0 = tcg_temp_local_new(TCG_TYPE_TL);
6100
            tcg_gen_mov_tl(t0, cpu_T[0]);
6101
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, label1);
6102
            if (b & 1) {
6103
                tcg_gen_helper_1_1(helper_bsr, cpu_T[0], t0);
6104
            } else {
6105
                tcg_gen_helper_1_1(helper_bsf, cpu_T[0], t0);
6106
            }
6107
            gen_op_mov_reg_T0(ot, reg);
6108
            tcg_gen_movi_tl(cpu_cc_dst, 1);
6109
            gen_set_label(label1);
6110
            tcg_gen_discard_tl(cpu_cc_src);
6111
            s->cc_op = CC_OP_LOGICB + ot;
6112
            tcg_temp_free(t0);
6113
        }
6114
        break;
6115
        /************************/
6116
        /* bcd */
6117
    case 0x27: /* daa */
6118
        if (CODE64(s))
6119
            goto illegal_op;
6120
        if (s->cc_op != CC_OP_DYNAMIC)
6121
            gen_op_set_cc_op(s->cc_op);
6122
        tcg_gen_helper_0_0(helper_daa);
6123
        s->cc_op = CC_OP_EFLAGS;
6124
        break;
6125
    case 0x2f: /* das */
6126
        if (CODE64(s))
6127
            goto illegal_op;
6128
        if (s->cc_op != CC_OP_DYNAMIC)
6129
            gen_op_set_cc_op(s->cc_op);
6130
        tcg_gen_helper_0_0(helper_das);
6131
        s->cc_op = CC_OP_EFLAGS;
6132
        break;
6133
    case 0x37: /* aaa */
6134
        if (CODE64(s))
6135
            goto illegal_op;
6136
        if (s->cc_op != CC_OP_DYNAMIC)
6137
            gen_op_set_cc_op(s->cc_op);
6138
        tcg_gen_helper_0_0(helper_aaa);
6139
        s->cc_op = CC_OP_EFLAGS;
6140
        break;
6141
    case 0x3f: /* aas */
6142
        if (CODE64(s))
6143
            goto illegal_op;
6144
        if (s->cc_op != CC_OP_DYNAMIC)
6145
            gen_op_set_cc_op(s->cc_op);
6146
        tcg_gen_helper_0_0(helper_aas);
6147
        s->cc_op = CC_OP_EFLAGS;
6148
        break;
6149
    case 0xd4: /* aam */
6150
        if (CODE64(s))
6151
            goto illegal_op;
6152
        val = ldub_code(s->pc++);
6153
        if (val == 0) {
6154
            gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
6155
        } else {
6156
            tcg_gen_helper_0_1(helper_aam, tcg_const_i32(val));
6157
            s->cc_op = CC_OP_LOGICB;
6158
        }
6159
        break;
6160
    case 0xd5: /* aad */
6161
        if (CODE64(s))
6162
            goto illegal_op;
6163
        val = ldub_code(s->pc++);
6164
        tcg_gen_helper_0_1(helper_aad, tcg_const_i32(val));
6165
        s->cc_op = CC_OP_LOGICB;
6166
        break;
6167
        /************************/
6168
        /* misc */
6169
    case 0x90: /* nop */
6170
        /* XXX: xchg + rex handling */
6171
        /* XXX: correct lock test for all insn */
6172
        if (prefixes & PREFIX_LOCK)
6173
            goto illegal_op;
6174
        if (prefixes & PREFIX_REPZ) {
6175
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_PAUSE);
6176
        }
6177
        break;
6178
    case 0x9b: /* fwait */
6179
        if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
6180
            (HF_MP_MASK | HF_TS_MASK)) {
6181
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6182
        } else {
6183
            if (s->cc_op != CC_OP_DYNAMIC)
6184
                gen_op_set_cc_op(s->cc_op);
6185
            gen_jmp_im(pc_start - s->cs_base);
6186
            tcg_gen_helper_0_0(helper_fwait);
6187
        }
6188
        break;
6189
    case 0xcc: /* int3 */
6190
        if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_SWINT))
6191
            break;
6192
        gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
6193
        break;
6194
    case 0xcd: /* int N */
6195
        val = ldub_code(s->pc++);
6196
        if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_SWINT))
6197
            break;
6198
        if (s->vm86 && s->iopl != 3) {
6199
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6200
        } else {
6201
            gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
6202
        }
6203
        break;
6204
    case 0xce: /* into */
6205
        if (CODE64(s))
6206
            goto illegal_op;
6207
        if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_SWINT))
6208
            break;
6209
        if (s->cc_op != CC_OP_DYNAMIC)
6210
            gen_op_set_cc_op(s->cc_op);
6211
        gen_jmp_im(pc_start - s->cs_base);
6212
        tcg_gen_helper_0_1(helper_into, tcg_const_i32(s->pc - pc_start));
6213
        break;
6214
    case 0xf1: /* icebp (undocumented, exits to external debugger) */
6215
        if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP))
6216
            break;
6217
#if 1
6218
        gen_debug(s, pc_start - s->cs_base);
6219
#else
6220
        /* start debug */
6221
        tb_flush(cpu_single_env);
6222
        cpu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
6223
#endif
6224
        break;
6225
    case 0xfa: /* cli */
6226
        if (!s->vm86) {
6227
            if (s->cpl <= s->iopl) {
6228
                tcg_gen_helper_0_0(helper_cli);
6229
            } else {
6230
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6231
            }
6232
        } else {
6233
            if (s->iopl == 3) {
6234
                tcg_gen_helper_0_0(helper_cli);
6235
            } else {
6236
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6237
            }
6238
        }
6239
        break;
6240
    case 0xfb: /* sti */
6241
        if (!s->vm86) {
6242
            if (s->cpl <= s->iopl) {
6243
            gen_sti:
6244
                tcg_gen_helper_0_0(helper_sti);
6245
                /* interruptions are enabled only the first insn after sti */
6246
                /* If several instructions disable interrupts, only the
6247
                   _first_ does it */
6248
                if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
6249
                    tcg_gen_helper_0_0(helper_set_inhibit_irq);
6250
                /* give a chance to handle pending irqs */
6251
                gen_jmp_im(s->pc - s->cs_base);
6252
                gen_eob(s);
6253
            } else {
6254
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6255
            }
6256
        } else {
6257
            if (s->iopl == 3) {
6258
                goto gen_sti;
6259
            } else {
6260
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6261
            }
6262
        }
6263
        break;
6264
    case 0x62: /* bound */
6265
        if (CODE64(s))
6266
            goto illegal_op;
6267
        ot = dflag ? OT_LONG : OT_WORD;
6268
        modrm = ldub_code(s->pc++);
6269
        reg = (modrm >> 3) & 7;
6270
        mod = (modrm >> 6) & 3;
6271
        if (mod == 3)
6272
            goto illegal_op;
6273
        gen_op_mov_TN_reg(ot, 0, reg);
6274
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6275
        gen_jmp_im(pc_start - s->cs_base);
6276
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6277
        if (ot == OT_WORD)
6278
            tcg_gen_helper_0_2(helper_boundw, cpu_A0, cpu_tmp2_i32);
6279
        else
6280
            tcg_gen_helper_0_2(helper_boundl, cpu_A0, cpu_tmp2_i32);
6281
        break;
6282
    case 0x1c8 ... 0x1cf: /* bswap reg */
6283
        reg = (b & 7) | REX_B(s);
6284
#ifdef TARGET_X86_64
6285
        if (dflag == 2) {
6286
            gen_op_mov_TN_reg(OT_QUAD, 0, reg);
6287
            tcg_gen_bswap_i64(cpu_T[0], cpu_T[0]);
6288
            gen_op_mov_reg_T0(OT_QUAD, reg);
6289
        } else
6290
        {
6291
            TCGv tmp0;
6292
            gen_op_mov_TN_reg(OT_LONG, 0, reg);
6293
            
6294
            tmp0 = tcg_temp_new(TCG_TYPE_I32);
6295
            tcg_gen_trunc_i64_i32(tmp0, cpu_T[0]);
6296
            tcg_gen_bswap_i32(tmp0, tmp0);
6297
            tcg_gen_extu_i32_i64(cpu_T[0], tmp0);
6298
            gen_op_mov_reg_T0(OT_LONG, reg);
6299
        }
6300
#else
6301
        {
6302
            gen_op_mov_TN_reg(OT_LONG, 0, reg);
6303
            tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]);
6304
            gen_op_mov_reg_T0(OT_LONG, reg);
6305
        }
6306
#endif
6307
        break;
6308
    case 0xd6: /* salc */
6309
        if (CODE64(s))
6310
            goto illegal_op;
6311
        if (s->cc_op != CC_OP_DYNAMIC)
6312
            gen_op_set_cc_op(s->cc_op);
6313
        gen_compute_eflags_c(cpu_T[0]);
6314
        tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
6315
        gen_op_mov_reg_T0(OT_BYTE, R_EAX);
6316
        break;
6317
    case 0xe0: /* loopnz */
6318
    case 0xe1: /* loopz */
6319
    case 0xe2: /* loop */
6320
    case 0xe3: /* jecxz */
6321
        {
6322
            int l1, l2, l3;
6323

    
6324
            tval = (int8_t)insn_get(s, OT_BYTE);
6325
            next_eip = s->pc - s->cs_base;
6326
            tval += next_eip;
6327
            if (s->dflag == 0)
6328
                tval &= 0xffff;
6329

    
6330
            l1 = gen_new_label();
6331
            l2 = gen_new_label();
6332
            l3 = gen_new_label();
6333
            b &= 3;
6334
            switch(b) {
6335
            case 0: /* loopnz */
6336
            case 1: /* loopz */
6337
                if (s->cc_op != CC_OP_DYNAMIC)
6338
                    gen_op_set_cc_op(s->cc_op);
6339
                gen_op_add_reg_im(s->aflag, R_ECX, -1);
6340
                gen_op_jz_ecx(s->aflag, l3);
6341
                gen_compute_eflags(cpu_tmp0);
6342
                tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_Z);
6343
                if (b == 0) {
6344
                    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
6345
                } else {
6346
                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, l1);
6347
                }
6348
                break;
6349
            case 2: /* loop */
6350
                gen_op_add_reg_im(s->aflag, R_ECX, -1);
6351
                gen_op_jnz_ecx(s->aflag, l1);
6352
                break;
6353
            default:
6354
            case 3: /* jcxz */
6355
                gen_op_jz_ecx(s->aflag, l1);
6356
                break;
6357
            }
6358

    
6359
            gen_set_label(l3);
6360
            gen_jmp_im(next_eip);
6361
            tcg_gen_br(l2);
6362

    
6363
            gen_set_label(l1);
6364
            gen_jmp_im(tval);
6365
            gen_set_label(l2);
6366
            gen_eob(s);
6367
        }
6368
        break;
6369
    case 0x130: /* wrmsr */
6370
    case 0x132: /* rdmsr */
6371
        if (s->cpl != 0) {
6372
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6373
        } else {
6374
            int retval = 0;
6375
            if (b & 2) {
6376
                retval = gen_svm_check_intercept_param(s, pc_start, SVM_EXIT_MSR, 0);
6377
                tcg_gen_helper_0_0(helper_rdmsr);
6378
            } else {
6379
                retval = gen_svm_check_intercept_param(s, pc_start, SVM_EXIT_MSR, 1);
6380
                tcg_gen_helper_0_0(helper_wrmsr);
6381
            }
6382
            if(retval)
6383
                gen_eob(s);
6384
        }
6385
        break;
6386
    case 0x131: /* rdtsc */
6387
        if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_RDTSC))
6388
            break;
6389
        gen_jmp_im(pc_start - s->cs_base);
6390
        tcg_gen_helper_0_0(helper_rdtsc);
6391
        break;
6392
    case 0x133: /* rdpmc */
6393
        gen_jmp_im(pc_start - s->cs_base);
6394
        tcg_gen_helper_0_0(helper_rdpmc);
6395
        break;
6396
    case 0x134: /* sysenter */
6397
        if (CODE64(s))
6398
            goto illegal_op;
6399
        if (!s->pe) {
6400
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6401
        } else {
6402
            if (s->cc_op != CC_OP_DYNAMIC) {
6403
                gen_op_set_cc_op(s->cc_op);
6404
                s->cc_op = CC_OP_DYNAMIC;
6405
            }
6406
            gen_jmp_im(pc_start - s->cs_base);
6407
            tcg_gen_helper_0_0(helper_sysenter);
6408
            gen_eob(s);
6409
        }
6410
        break;
6411
    case 0x135: /* sysexit */
6412
        if (CODE64(s))
6413
            goto illegal_op;
6414
        if (!s->pe) {
6415
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6416
        } else {
6417
            if (s->cc_op != CC_OP_DYNAMIC) {
6418
                gen_op_set_cc_op(s->cc_op);
6419
                s->cc_op = CC_OP_DYNAMIC;
6420
            }
6421
            gen_jmp_im(pc_start - s->cs_base);
6422
            tcg_gen_helper_0_0(helper_sysexit);
6423
            gen_eob(s);
6424
        }
6425
        break;
6426
#ifdef TARGET_X86_64
6427
    case 0x105: /* syscall */
6428
        /* XXX: is it usable in real mode ? */
6429
        if (s->cc_op != CC_OP_DYNAMIC) {
6430
            gen_op_set_cc_op(s->cc_op);
6431
            s->cc_op = CC_OP_DYNAMIC;
6432
        }
6433
        gen_jmp_im(pc_start - s->cs_base);
6434
        tcg_gen_helper_0_1(helper_syscall, tcg_const_i32(s->pc - pc_start));
6435
        gen_eob(s);
6436
        break;
6437
    case 0x107: /* sysret */
6438
        if (!s->pe) {
6439
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6440
        } else {
6441
            if (s->cc_op != CC_OP_DYNAMIC) {
6442
                gen_op_set_cc_op(s->cc_op);
6443
                s->cc_op = CC_OP_DYNAMIC;
6444
            }
6445
            gen_jmp_im(pc_start - s->cs_base);
6446
            tcg_gen_helper_0_1(helper_sysret, tcg_const_i32(s->dflag));
6447
            /* condition codes are modified only in long mode */
6448
            if (s->lma)
6449
                s->cc_op = CC_OP_EFLAGS;
6450
            gen_eob(s);
6451
        }
6452
        break;
6453
#endif
6454
    case 0x1a2: /* cpuid */
6455
        if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_CPUID))
6456
            break;
6457
        tcg_gen_helper_0_0(helper_cpuid);
6458
        break;
6459
    case 0xf4: /* hlt */
6460
        if (s->cpl != 0) {
6461
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6462
        } else {
6463
            if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_HLT))
6464
                break;
6465
            if (s->cc_op != CC_OP_DYNAMIC)
6466
                gen_op_set_cc_op(s->cc_op);
6467
            gen_jmp_im(s->pc - s->cs_base);
6468
            tcg_gen_helper_0_0(helper_hlt);
6469
            s->is_jmp = 3;
6470
        }
6471
        break;
6472
    case 0x100:
6473
        modrm = ldub_code(s->pc++);
6474
        mod = (modrm >> 6) & 3;
6475
        op = (modrm >> 3) & 7;
6476
        switch(op) {
6477
        case 0: /* sldt */
6478
            if (!s->pe || s->vm86)
6479
                goto illegal_op;
6480
            if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ))
6481
                break;
6482
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,ldt.selector));
6483
            ot = OT_WORD;
6484
            if (mod == 3)
6485
                ot += s->dflag;
6486
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
6487
            break;
6488
        case 2: /* lldt */
6489
            if (!s->pe || s->vm86)
6490
                goto illegal_op;
6491
            if (s->cpl != 0) {
6492
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6493
            } else {
6494
                if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE))
6495
                    break;
6496
                gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
6497
                gen_jmp_im(pc_start - s->cs_base);
6498
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6499
                tcg_gen_helper_0_1(helper_lldt, cpu_tmp2_i32);
6500
            }
6501
            break;
6502
        case 1: /* str */
6503
            if (!s->pe || s->vm86)
6504
                goto illegal_op;
6505
            if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ))
6506
                break;
6507
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,tr.selector));
6508
            ot = OT_WORD;
6509
            if (mod == 3)
6510
                ot += s->dflag;
6511
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
6512
            break;
6513
        case 3: /* ltr */
6514
            if (!s->pe || s->vm86)
6515
                goto illegal_op;
6516
            if (s->cpl != 0) {
6517
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6518
            } else {
6519
                if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE))
6520
                    break;
6521
                gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
6522
                gen_jmp_im(pc_start - s->cs_base);
6523
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6524
                tcg_gen_helper_0_1(helper_ltr, cpu_tmp2_i32);
6525
            }
6526
            break;
6527
        case 4: /* verr */
6528
        case 5: /* verw */
6529
            if (!s->pe || s->vm86)
6530
                goto illegal_op;
6531
            gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
6532
            if (s->cc_op != CC_OP_DYNAMIC)
6533
                gen_op_set_cc_op(s->cc_op);
6534
            if (op == 4)
6535
                tcg_gen_helper_0_1(helper_verr, cpu_T[0]);
6536
            else
6537
                tcg_gen_helper_0_1(helper_verw, cpu_T[0]);
6538
            s->cc_op = CC_OP_EFLAGS;
6539
            break;
6540
        default:
6541
            goto illegal_op;
6542
        }
6543
        break;
6544
    case 0x101:
6545
        modrm = ldub_code(s->pc++);
6546
        mod = (modrm >> 6) & 3;
6547
        op = (modrm >> 3) & 7;
6548
        rm = modrm & 7;
6549
        switch(op) {
6550
        case 0: /* sgdt */
6551
            if (mod == 3)
6552
                goto illegal_op;
6553
            if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ))
6554
                break;
6555
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6556
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.limit));
6557
            gen_op_st_T0_A0(OT_WORD + s->mem_index);
6558
            gen_add_A0_im(s, 2);
6559
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.base));
6560
            if (!s->dflag)
6561
                gen_op_andl_T0_im(0xffffff);
6562
            gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
6563
            break;
6564
        case 1:
6565
            if (mod == 3) {
6566
                switch (rm) {
6567
                case 0: /* monitor */
6568
                    if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
6569
                        s->cpl != 0)
6570
                        goto illegal_op;
6571
                    if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_MONITOR))
6572
                        break;
6573
                    gen_jmp_im(pc_start - s->cs_base);
6574
#ifdef TARGET_X86_64
6575
                    if (s->aflag == 2) {
6576
                        gen_op_movq_A0_reg(R_EAX);
6577
                    } else
6578
#endif
6579
                    {
6580
                        gen_op_movl_A0_reg(R_EAX);
6581
                        if (s->aflag == 0)
6582
                            gen_op_andl_A0_ffff();
6583
                    }
6584
                    gen_add_A0_ds_seg(s);
6585
                    tcg_gen_helper_0_1(helper_monitor, cpu_A0);
6586
                    break;
6587
                case 1: /* mwait */
6588
                    if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
6589
                        s->cpl != 0)
6590
                        goto illegal_op;
6591
                    if (s->cc_op != CC_OP_DYNAMIC) {
6592
                        gen_op_set_cc_op(s->cc_op);
6593
                        s->cc_op = CC_OP_DYNAMIC;
6594
                    }
6595
                    if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_MWAIT))
6596
                        break;
6597
                    gen_jmp_im(s->pc - s->cs_base);
6598
                    tcg_gen_helper_0_0(helper_mwait);
6599
                    gen_eob(s);
6600
                    break;
6601
                default:
6602
                    goto illegal_op;
6603
                }
6604
            } else { /* sidt */
6605
                if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ))
6606
                    break;
6607
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6608
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.limit));
6609
                gen_op_st_T0_A0(OT_WORD + s->mem_index);
6610
                gen_add_A0_im(s, 2);
6611
                tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.base));
6612
                if (!s->dflag)
6613
                    gen_op_andl_T0_im(0xffffff);
6614
                gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
6615
            }
6616
            break;
6617
        case 2: /* lgdt */
6618
        case 3: /* lidt */
6619
            if (mod == 3) {
6620
                switch(rm) {
6621
                case 0: /* VMRUN */
6622
                    if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VMRUN))
6623
                        break;
6624
                    if (s->cc_op != CC_OP_DYNAMIC)
6625
                        gen_op_set_cc_op(s->cc_op);
6626
                    gen_jmp_im(s->pc - s->cs_base);
6627
                    tcg_gen_helper_0_0(helper_vmrun);
6628
                    s->cc_op = CC_OP_EFLAGS;
6629
                    gen_eob(s);
6630
                    break;
6631
                case 1: /* VMMCALL */
6632
                    if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VMMCALL))
6633
                         break;
6634
                    /* FIXME: cause #UD if hflags & SVM */
6635
                    tcg_gen_helper_0_0(helper_vmmcall);
6636
                    break;
6637
                case 2: /* VMLOAD */
6638
                    if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VMLOAD))
6639
                         break;
6640
                    tcg_gen_helper_0_0(helper_vmload);
6641
                    break;
6642
                case 3: /* VMSAVE */
6643
                    if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VMSAVE))
6644
                         break;
6645
                    tcg_gen_helper_0_0(helper_vmsave);
6646
                    break;
6647
                case 4: /* STGI */
6648
                    if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_STGI))
6649
                         break;
6650
                    tcg_gen_helper_0_0(helper_stgi);
6651
                    break;
6652
                case 5: /* CLGI */
6653
                    if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_CLGI))
6654
                         break;
6655
                    tcg_gen_helper_0_0(helper_clgi);
6656
                    break;
6657
                case 6: /* SKINIT */
6658
                    if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_SKINIT))
6659
                         break;
6660
                    tcg_gen_helper_0_0(helper_skinit);
6661
                    break;
6662
                case 7: /* INVLPGA */
6663
                    if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_INVLPGA))
6664
                         break;
6665
                    tcg_gen_helper_0_0(helper_invlpga);
6666
                    break;
6667
                default:
6668
                    goto illegal_op;
6669
                }
6670
            } else if (s->cpl != 0) {
6671
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6672
            } else {
6673
                if (gen_svm_check_intercept(s, pc_start,
6674
                                            op==2 ? SVM_EXIT_GDTR_WRITE : SVM_EXIT_IDTR_WRITE))
6675
                    break;
6676
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6677
                gen_op_ld_T1_A0(OT_WORD + s->mem_index);
6678
                gen_add_A0_im(s, 2);
6679
                gen_op_ld_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
6680
                if (!s->dflag)
6681
                    gen_op_andl_T0_im(0xffffff);
6682
                if (op == 2) {
6683
                    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,gdt.base));
6684
                    tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,gdt.limit));
6685
                } else {
6686
                    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,idt.base));
6687
                    tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,idt.limit));
6688
                }
6689
            }
6690
            break;
6691
        case 4: /* smsw */
6692
            if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0))
6693
                break;
6694
            tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]));
6695
            gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 1);
6696
            break;
6697
        case 6: /* lmsw */
6698
            if (s->cpl != 0) {
6699
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6700
            } else {
6701
                if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0))
6702
                    break;
6703
                gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
6704
                tcg_gen_helper_0_1(helper_lmsw, cpu_T[0]);
6705
                gen_jmp_im(s->pc - s->cs_base);
6706
                gen_eob(s);
6707
            }
6708
            break;
6709
        case 7: /* invlpg */
6710
            if (s->cpl != 0) {
6711
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6712
            } else {
6713
                if (mod == 3) {
6714
#ifdef TARGET_X86_64
6715
                    if (CODE64(s) && rm == 0) {
6716
                        /* swapgs */
6717
                        tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,segs[R_GS].base));
6718
                        tcg_gen_ld_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,kernelgsbase));
6719
                        tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,segs[R_GS].base));
6720
                        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,kernelgsbase));
6721
                    } else
6722
#endif
6723
                    {
6724
                        goto illegal_op;
6725
                    }
6726
                } else {
6727
                    if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_INVLPG))
6728
                        break;
6729
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6730
                    tcg_gen_helper_0_1(helper_invlpg, cpu_A0);
6731
                    gen_jmp_im(s->pc - s->cs_base);
6732
                    gen_eob(s);
6733
                }
6734
            }
6735
            break;
6736
        default:
6737
            goto illegal_op;
6738
        }
6739
        break;
6740
    case 0x108: /* invd */
6741
    case 0x109: /* wbinvd */
6742
        if (s->cpl != 0) {
6743
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6744
        } else {
6745
            if (gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD))
6746
                break;
6747
            /* nothing to do */
6748
        }
6749
        break;
6750
    case 0x63: /* arpl or movslS (x86_64) */
6751
#ifdef TARGET_X86_64
6752
        if (CODE64(s)) {
6753
            int d_ot;
6754
            /* d_ot is the size of destination */
6755
            d_ot = dflag + OT_WORD;
6756

    
6757
            modrm = ldub_code(s->pc++);
6758
            reg = ((modrm >> 3) & 7) | rex_r;
6759
            mod = (modrm >> 6) & 3;
6760
            rm = (modrm & 7) | REX_B(s);
6761

    
6762
            if (mod == 3) {
6763
                gen_op_mov_TN_reg(OT_LONG, 0, rm);
6764
                /* sign extend */
6765
                if (d_ot == OT_QUAD)
6766
                    tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
6767
                gen_op_mov_reg_T0(d_ot, reg);
6768
            } else {
6769
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6770
                if (d_ot == OT_QUAD) {
6771
                    gen_op_lds_T0_A0(OT_LONG + s->mem_index);
6772
                } else {
6773
                    gen_op_ld_T0_A0(OT_LONG + s->mem_index);
6774
                }
6775
                gen_op_mov_reg_T0(d_ot, reg);
6776
            }
6777
        } else
6778
#endif
6779
        {
6780
            int label1;
6781
            TCGv t0, t1, t2;
6782

    
6783
            if (!s->pe || s->vm86)
6784
                goto illegal_op;
6785
            t0 = tcg_temp_local_new(TCG_TYPE_TL);
6786
            t1 = tcg_temp_local_new(TCG_TYPE_TL);
6787
            t2 = tcg_temp_local_new(TCG_TYPE_TL);
6788
            ot = OT_WORD;
6789
            modrm = ldub_code(s->pc++);
6790
            reg = (modrm >> 3) & 7;
6791
            mod = (modrm >> 6) & 3;
6792
            rm = modrm & 7;
6793
            if (mod != 3) {
6794
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6795
                gen_op_ld_v(ot + s->mem_index, t0, cpu_A0);
6796
            } else {
6797
                gen_op_mov_v_reg(ot, t0, rm);
6798
            }
6799
            gen_op_mov_v_reg(ot, t1, reg);
6800
            tcg_gen_andi_tl(cpu_tmp0, t0, 3);
6801
            tcg_gen_andi_tl(t1, t1, 3);
6802
            tcg_gen_movi_tl(t2, 0);
6803
            label1 = gen_new_label();
6804
            tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, t1, label1);
6805
            tcg_gen_andi_tl(t0, t0, ~3);
6806
            tcg_gen_or_tl(t0, t0, t1);
6807
            tcg_gen_movi_tl(t2, CC_Z);
6808
            gen_set_label(label1);
6809
            if (mod != 3) {
6810
                gen_op_st_v(ot + s->mem_index, t0, cpu_A0);
6811
            } else {
6812
                gen_op_mov_reg_v(ot, rm, t0);
6813
            }
6814
            if (s->cc_op != CC_OP_DYNAMIC)
6815
                gen_op_set_cc_op(s->cc_op);
6816
            gen_compute_eflags(cpu_cc_src);
6817
            tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
6818
            tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
6819
            s->cc_op = CC_OP_EFLAGS;
6820
            tcg_temp_free(t0);
6821
            tcg_temp_free(t1);
6822
            tcg_temp_free(t2);
6823
        }
6824
        break;
6825
    case 0x102: /* lar */
6826
    case 0x103: /* lsl */
6827
        {
6828
            int label1;
6829
            TCGv t0;
6830
            if (!s->pe || s->vm86)
6831
                goto illegal_op;
6832
            ot = dflag ? OT_LONG : OT_WORD;
6833
            modrm = ldub_code(s->pc++);
6834
            reg = ((modrm >> 3) & 7) | rex_r;
6835
            gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
6836
            t0 = tcg_temp_local_new(TCG_TYPE_TL);
6837
            if (s->cc_op != CC_OP_DYNAMIC)
6838
                gen_op_set_cc_op(s->cc_op);
6839
            if (b == 0x102)
6840
                tcg_gen_helper_1_1(helper_lar, t0, cpu_T[0]);
6841
            else
6842
                tcg_gen_helper_1_1(helper_lsl, t0, cpu_T[0]);
6843
            tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
6844
            label1 = gen_new_label();
6845
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
6846
            gen_op_mov_reg_v(ot, reg, t0);
6847
            gen_set_label(label1);
6848
            s->cc_op = CC_OP_EFLAGS;
6849
            tcg_temp_free(t0);
6850
        }
6851
        break;
6852
    case 0x118:
6853
        modrm = ldub_code(s->pc++);
6854
        mod = (modrm >> 6) & 3;
6855
        op = (modrm >> 3) & 7;
6856
        switch(op) {
6857
        case 0: /* prefetchnta */
6858
        case 1: /* prefetchnt0 */
6859
        case 2: /* prefetchnt0 */
6860
        case 3: /* prefetchnt0 */
6861
            if (mod == 3)
6862
                goto illegal_op;
6863
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6864
            /* nothing more to do */
6865
            break;
6866
        default: /* nop (multi byte) */
6867
            gen_nop_modrm(s, modrm);
6868
            break;
6869
        }
6870
        break;
6871
    case 0x119 ... 0x11f: /* nop (multi byte) */
6872
        modrm = ldub_code(s->pc++);
6873
        gen_nop_modrm(s, modrm);
6874
        break;
6875
    case 0x120: /* mov reg, crN */
6876
    case 0x122: /* mov crN, reg */
6877
        if (s->cpl != 0) {
6878
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6879
        } else {
6880
            modrm = ldub_code(s->pc++);
6881
            if ((modrm & 0xc0) != 0xc0)
6882
                goto illegal_op;
6883
            rm = (modrm & 7) | REX_B(s);
6884
            reg = ((modrm >> 3) & 7) | rex_r;
6885
            if (CODE64(s))
6886
                ot = OT_QUAD;
6887
            else
6888
                ot = OT_LONG;
6889
            switch(reg) {
6890
            case 0:
6891
            case 2:
6892
            case 3:
6893
            case 4:
6894
            case 8:
6895
                if (b & 2) {
6896
                    gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0 + reg);
6897
                    gen_op_mov_TN_reg(ot, 0, rm);
6898
                    tcg_gen_helper_0_2(helper_movl_crN_T0, 
6899
                                       tcg_const_i32(reg), cpu_T[0]);
6900
                    gen_jmp_im(s->pc - s->cs_base);
6901
                    gen_eob(s);
6902
                } else {
6903
                    gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0 + reg);
6904
#if !defined(CONFIG_USER_ONLY)
6905
                    if (reg == 8)
6906
                        tcg_gen_helper_1_0(helper_movtl_T0_cr8, cpu_T[0]);
6907
                    else
6908
#endif
6909
                        tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[reg]));
6910
                    gen_op_mov_reg_T0(ot, rm);
6911
                }
6912
                break;
6913
            default:
6914
                goto illegal_op;
6915
            }
6916
        }
6917
        break;
6918
    case 0x121: /* mov reg, drN */
6919
    case 0x123: /* mov drN, reg */
6920
        if (s->cpl != 0) {
6921
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6922
        } else {
6923
            modrm = ldub_code(s->pc++);
6924
            if ((modrm & 0xc0) != 0xc0)
6925
                goto illegal_op;
6926
            rm = (modrm & 7) | REX_B(s);
6927
            reg = ((modrm >> 3) & 7) | rex_r;
6928
            if (CODE64(s))
6929
                ot = OT_QUAD;
6930
            else
6931
                ot = OT_LONG;
6932
            /* XXX: do it dynamically with CR4.DE bit */
6933
            if (reg == 4 || reg == 5 || reg >= 8)
6934
                goto illegal_op;
6935
            if (b & 2) {
6936
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
6937
                gen_op_mov_TN_reg(ot, 0, rm);
6938
                tcg_gen_helper_0_2(helper_movl_drN_T0,
6939
                                   tcg_const_i32(reg), cpu_T[0]);
6940
                gen_jmp_im(s->pc - s->cs_base);
6941
                gen_eob(s);
6942
            } else {
6943
                gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
6944
                tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,dr[reg]));
6945
                gen_op_mov_reg_T0(ot, rm);
6946
            }
6947
        }
6948
        break;
6949
    case 0x106: /* clts */
6950
        if (s->cpl != 0) {
6951
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6952
        } else {
6953
            gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
6954
            tcg_gen_helper_0_0(helper_clts);
6955
            /* abort block because static cpu state changed */
6956
            gen_jmp_im(s->pc - s->cs_base);
6957
            gen_eob(s);
6958
        }
6959
        break;
6960
    /* MMX/3DNow!/SSE/SSE2/SSE3 support */
6961
    case 0x1c3: /* MOVNTI reg, mem */
6962
        if (!(s->cpuid_features & CPUID_SSE2))
6963
            goto illegal_op;
6964
        ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
6965
        modrm = ldub_code(s->pc++);
6966
        mod = (modrm >> 6) & 3;
6967
        if (mod == 3)
6968
            goto illegal_op;
6969
        reg = ((modrm >> 3) & 7) | rex_r;
6970
        /* generate a generic store */
6971
        gen_ldst_modrm(s, modrm, ot, reg, 1);
6972
        break;
6973
    case 0x1ae:
6974
        modrm = ldub_code(s->pc++);
6975
        mod = (modrm >> 6) & 3;
6976
        op = (modrm >> 3) & 7;
6977
        switch(op) {
6978
        case 0: /* fxsave */
6979
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
6980
                (s->flags & HF_EM_MASK))
6981
                goto illegal_op;
6982
            if (s->flags & HF_TS_MASK) {
6983
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6984
                break;
6985
            }
6986
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6987
            if (s->cc_op != CC_OP_DYNAMIC)
6988
                gen_op_set_cc_op(s->cc_op);
6989
            gen_jmp_im(pc_start - s->cs_base);
6990
            tcg_gen_helper_0_2(helper_fxsave, 
6991
                               cpu_A0, tcg_const_i32((s->dflag == 2)));
6992
            break;
6993
        case 1: /* fxrstor */
6994
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
6995
                (s->flags & HF_EM_MASK))
6996
                goto illegal_op;
6997
            if (s->flags & HF_TS_MASK) {
6998
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6999
                break;
7000
            }
7001
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7002
            if (s->cc_op != CC_OP_DYNAMIC)
7003
                gen_op_set_cc_op(s->cc_op);
7004
            gen_jmp_im(pc_start - s->cs_base);
7005
            tcg_gen_helper_0_2(helper_fxrstor,
7006
                               cpu_A0, tcg_const_i32((s->dflag == 2)));
7007
            break;
7008
        case 2: /* ldmxcsr */
7009
        case 3: /* stmxcsr */
7010
            if (s->flags & HF_TS_MASK) {
7011
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7012
                break;
7013
            }
7014
            if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
7015
                mod == 3)
7016
                goto illegal_op;
7017
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7018
            if (op == 2) {
7019
                gen_op_ld_T0_A0(OT_LONG + s->mem_index);
7020
                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
7021
            } else {
7022
                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
7023
                gen_op_st_T0_A0(OT_LONG + s->mem_index);
7024
            }
7025
            break;
7026
        case 5: /* lfence */
7027
        case 6: /* mfence */
7028
            if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE))
7029
                goto illegal_op;
7030
            break;
7031
        case 7: /* sfence / clflush */
7032
            if ((modrm & 0xc7) == 0xc0) {
7033
                /* sfence */
7034
                /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
7035
                if (!(s->cpuid_features & CPUID_SSE))
7036
                    goto illegal_op;
7037
            } else {
7038
                /* clflush */
7039
                if (!(s->cpuid_features & CPUID_CLFLUSH))
7040
                    goto illegal_op;
7041
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7042
            }
7043
            break;
7044
        default:
7045
            goto illegal_op;
7046
        }
7047
        break;
7048
    case 0x10d: /* 3DNow! prefetch(w) */
7049
        modrm = ldub_code(s->pc++);
7050
        mod = (modrm >> 6) & 3;
7051
        if (mod == 3)
7052
            goto illegal_op;
7053
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
7054
        /* ignore for now */
7055
        break;
7056
    case 0x1aa: /* rsm */
7057
        if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM))
7058
            break;
7059
        if (!(s->flags & HF_SMM_MASK))
7060
            goto illegal_op;
7061
        if (s->cc_op != CC_OP_DYNAMIC) {
7062
            gen_op_set_cc_op(s->cc_op);
7063
            s->cc_op = CC_OP_DYNAMIC;
7064
        }
7065
        gen_jmp_im(s->pc - s->cs_base);
7066
        tcg_gen_helper_0_0(helper_rsm);
7067
        gen_eob(s);
7068
        break;
7069
    case 0x10e ... 0x10f:
7070
        /* 3DNow! instructions, ignore prefixes */
7071
        s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
7072
    case 0x110 ... 0x117:
7073
    case 0x128 ... 0x12f:
7074
    case 0x150 ... 0x177:
7075
    case 0x17c ... 0x17f:
7076
    case 0x1c2:
7077
    case 0x1c4 ... 0x1c6:
7078
    case 0x1d0 ... 0x1fe:
7079
        gen_sse(s, b, pc_start, rex_r);
7080
        break;
7081
    default:
7082
        goto illegal_op;
7083
    }
7084
    /* lock generation */
7085
    if (s->prefix & PREFIX_LOCK)
7086
        tcg_gen_helper_0_0(helper_unlock);
7087
    return s->pc;
7088
 illegal_op:
7089
    if (s->prefix & PREFIX_LOCK)
7090
        tcg_gen_helper_0_0(helper_unlock);
7091
    /* XXX: ensure that no lock was generated */
7092
    gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
7093
    return s->pc;
7094
}
7095

    
7096
void optimize_flags_init(void)
7097
{
7098
#if TCG_TARGET_REG_BITS == 32
7099
    assert(sizeof(CCTable) == (1 << 3));
7100
#else
7101
    assert(sizeof(CCTable) == (1 << 4));
7102
#endif
7103
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
7104
    cpu_cc_op = tcg_global_mem_new(TCG_TYPE_I32,
7105
                                   TCG_AREG0, offsetof(CPUState, cc_op), "cc_op");
7106
    cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
7107
                                    TCG_AREG0, offsetof(CPUState, cc_src), "cc_src");
7108
    cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL,
7109
                                    TCG_AREG0, offsetof(CPUState, cc_dst), "cc_dst");
7110
    cpu_cc_tmp = tcg_global_mem_new(TCG_TYPE_TL,
7111
                                    TCG_AREG0, offsetof(CPUState, cc_tmp), "cc_tmp");
7112

    
7113
    /* register helpers */
7114

    
7115
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
7116
#include "helper.h"
7117
}
7118

    
7119
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
7120
   basic block 'tb'. If search_pc is TRUE, also generate PC
7121
   information for each intermediate instruction. */
7122
static inline int gen_intermediate_code_internal(CPUState *env,
7123
                                                 TranslationBlock *tb,
7124
                                                 int search_pc)
7125
{
7126
    DisasContext dc1, *dc = &dc1;
7127
    target_ulong pc_ptr;
7128
    uint16_t *gen_opc_end;
7129
    int j, lj, cflags;
7130
    uint64_t flags;
7131
    target_ulong pc_start;
7132
    target_ulong cs_base;
7133

    
7134
    /* generate intermediate code */
7135
    pc_start = tb->pc;
7136
    cs_base = tb->cs_base;
7137
    flags = tb->flags;
7138
    cflags = tb->cflags;
7139

    
7140
    dc->pe = (flags >> HF_PE_SHIFT) & 1;
7141
    dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
7142
    dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
7143
    dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
7144
    dc->f_st = 0;
7145
    dc->vm86 = (flags >> VM_SHIFT) & 1;
7146
    dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
7147
    dc->iopl = (flags >> IOPL_SHIFT) & 3;
7148
    dc->tf = (flags >> TF_SHIFT) & 1;
7149
    dc->singlestep_enabled = env->singlestep_enabled;
7150
    dc->cc_op = CC_OP_DYNAMIC;
7151
    dc->cs_base = cs_base;
7152
    dc->tb = tb;
7153
    dc->popl_esp_hack = 0;
7154
    /* select memory access functions */
7155
    dc->mem_index = 0;
7156
    if (flags & HF_SOFTMMU_MASK) {
7157
        if (dc->cpl == 3)
7158
            dc->mem_index = 2 * 4;
7159
        else
7160
            dc->mem_index = 1 * 4;
7161
    }
7162
    dc->cpuid_features = env->cpuid_features;
7163
    dc->cpuid_ext_features = env->cpuid_ext_features;
7164
    dc->cpuid_ext2_features = env->cpuid_ext2_features;
7165
    dc->cpuid_ext3_features = env->cpuid_ext3_features;
7166
#ifdef TARGET_X86_64
7167
    dc->lma = (flags >> HF_LMA_SHIFT) & 1;
7168
    dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
7169
#endif
7170
    dc->flags = flags;
7171
    dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
7172
                    (flags & HF_INHIBIT_IRQ_MASK)
7173
#ifndef CONFIG_SOFTMMU
7174
                    || (flags & HF_SOFTMMU_MASK)
7175
#endif
7176
                    );
7177
#if 0
7178
    /* check addseg logic */
7179
    if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
7180
        printf("ERROR addseg\n");
7181
#endif
7182

    
7183
    cpu_T[0] = tcg_temp_new(TCG_TYPE_TL);
7184
    cpu_T[1] = tcg_temp_new(TCG_TYPE_TL);
7185
    cpu_A0 = tcg_temp_new(TCG_TYPE_TL);
7186
    cpu_T3 = tcg_temp_new(TCG_TYPE_TL);
7187

    
7188
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
7189
    cpu_tmp1_i64 = tcg_temp_new(TCG_TYPE_I64);
7190
    cpu_tmp2_i32 = tcg_temp_new(TCG_TYPE_I32);
7191
    cpu_tmp3_i32 = tcg_temp_new(TCG_TYPE_I32);
7192
    cpu_tmp4 = tcg_temp_new(TCG_TYPE_TL);
7193
    cpu_tmp5 = tcg_temp_new(TCG_TYPE_TL);
7194
    cpu_tmp6 = tcg_temp_new(TCG_TYPE_TL);
7195
    cpu_ptr0 = tcg_temp_new(TCG_TYPE_PTR);
7196
    cpu_ptr1 = tcg_temp_new(TCG_TYPE_PTR);
7197

    
7198
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
7199

    
7200
    dc->is_jmp = DISAS_NEXT;
7201
    pc_ptr = pc_start;
7202
    lj = -1;
7203

    
7204
    for(;;) {
7205
        if (env->nb_breakpoints > 0) {
7206
            for(j = 0; j < env->nb_breakpoints; j++) {
7207
                if (env->breakpoints[j] == pc_ptr) {
7208
                    gen_debug(dc, pc_ptr - dc->cs_base);
7209
                    break;
7210
                }
7211
            }
7212
        }
7213
        if (search_pc) {
7214
            j = gen_opc_ptr - gen_opc_buf;
7215
            if (lj < j) {
7216
                lj++;
7217
                while (lj < j)
7218
                    gen_opc_instr_start[lj++] = 0;
7219
            }
7220
            gen_opc_pc[lj] = pc_ptr;
7221
            gen_opc_cc_op[lj] = dc->cc_op;
7222
            gen_opc_instr_start[lj] = 1;
7223
        }
7224
        pc_ptr = disas_insn(dc, pc_ptr);
7225
        /* stop translation if indicated */
7226
        if (dc->is_jmp)
7227
            break;
7228
        /* if single step mode, we generate only one instruction and
7229
           generate an exception */
7230
        /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
7231
           the flag and abort the translation to give the irqs a
7232
           change to be happen */
7233
        if (dc->tf || dc->singlestep_enabled ||
7234
            (flags & HF_INHIBIT_IRQ_MASK) ||
7235
            (cflags & CF_SINGLE_INSN)) {
7236
            gen_jmp_im(pc_ptr - dc->cs_base);
7237
            gen_eob(dc);
7238
            break;
7239
        }
7240
        /* if too long translation, stop generation too */
7241
        if (gen_opc_ptr >= gen_opc_end ||
7242
            (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32)) {
7243
            gen_jmp_im(pc_ptr - dc->cs_base);
7244
            gen_eob(dc);
7245
            break;
7246
        }
7247
    }
7248
    *gen_opc_ptr = INDEX_op_end;
7249
    /* we don't forget to fill the last values */
7250
    if (search_pc) {
7251
        j = gen_opc_ptr - gen_opc_buf;
7252
        lj++;
7253
        while (lj <= j)
7254
            gen_opc_instr_start[lj++] = 0;
7255
    }
7256

    
7257
#ifdef DEBUG_DISAS
7258
    if (loglevel & CPU_LOG_TB_CPU) {
7259
        cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
7260
    }
7261
    if (loglevel & CPU_LOG_TB_IN_ASM) {
7262
        int disas_flags;
7263
        fprintf(logfile, "----------------\n");
7264
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
7265
#ifdef TARGET_X86_64
7266
        if (dc->code64)
7267
            disas_flags = 2;
7268
        else
7269
#endif
7270
            disas_flags = !dc->code32;
7271
        target_disas(logfile, pc_start, pc_ptr - pc_start, disas_flags);
7272
        fprintf(logfile, "\n");
7273
    }
7274
#endif
7275

    
7276
    if (!search_pc)
7277
        tb->size = pc_ptr - pc_start;
7278
    return 0;
7279
}
7280

    
7281
int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
7282
{
7283
    return gen_intermediate_code_internal(env, tb, 0);
7284
}
7285

    
7286
int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
7287
{
7288
    return gen_intermediate_code_internal(env, tb, 1);
7289
}
7290

    
7291
void gen_pc_load(CPUState *env, TranslationBlock *tb,
7292
                unsigned long searched_pc, int pc_pos, void *puc)
7293
{
7294
    int cc_op;
7295
#ifdef DEBUG_DISAS
7296
    if (loglevel & CPU_LOG_TB_OP) {
7297
        int i;
7298
        fprintf(logfile, "RESTORE:\n");
7299
        for(i = 0;i <= pc_pos; i++) {
7300
            if (gen_opc_instr_start[i]) {
7301
                fprintf(logfile, "0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]);
7302
            }
7303
        }
7304
        fprintf(logfile, "spc=0x%08lx pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
7305
                searched_pc, pc_pos, gen_opc_pc[pc_pos] - tb->cs_base,
7306
                (uint32_t)tb->cs_base);
7307
    }
7308
#endif
7309
    env->eip = gen_opc_pc[pc_pos] - tb->cs_base;
7310
    cc_op = gen_opc_cc_op[pc_pos];
7311
    if (cc_op != CC_OP_DYNAMIC)
7312
        env->cc_op = cc_op;
7313
}