Statistics
| Branch: | Revision:

root / target-i386 / translate.c @ 914178d3

History | View | Annotate | Download (234.9 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 & HF_SVMI_MASK) {
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_tmp4, cpu_T[0], op2 - 1);
1515
                tcg_gen_sari_tl(cpu_T[0], cpu_T[0], op2);
1516
            } else {
1517
                gen_extu(ot, cpu_T[0]);
1518
                tcg_gen_shri_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1519
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], op2);
1520
            }
1521
        } else {
1522
            tcg_gen_shli_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1523
            tcg_gen_shli_tl(cpu_T[0], cpu_T[0], op2);
1524
        }
1525
    }
1526

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

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

    
1552
/* 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 void
2326
gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2327
                              uint32_t type, uint64_t param)
2328
{
2329
    /* no SVM activated; fast case */
2330
    if (likely(!(s->flags & HF_SVMI_MASK)))
2331
        return;
2332
    if (s->cc_op != CC_OP_DYNAMIC)
2333
        gen_op_set_cc_op(s->cc_op);
2334
    gen_jmp_im(pc_start - s->cs_base);
2335
    tcg_gen_helper_0_2(helper_svm_check_intercept_param, 
2336
                       tcg_const_i32(type), tcg_const_i64(param));
2337
}
2338

    
2339
static inline void
2340
gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
2341
{
2342
    gen_svm_check_intercept_param(s, pc_start, type, 0);
2343
}
2344

    
2345
static inline void gen_stack_update(DisasContext *s, int addend)
2346
{
2347
#ifdef TARGET_X86_64
2348
    if (CODE64(s)) {
2349
        gen_op_add_reg_im(2, R_ESP, addend);
2350
    } else
2351
#endif
2352
    if (s->ss32) {
2353
        gen_op_add_reg_im(1, R_ESP, addend);
2354
    } else {
2355
        gen_op_add_reg_im(0, R_ESP, addend);
2356
    }
2357
}
2358

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

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

    
2432
        if (s->ss32 && !s->addseg)
2433
            gen_op_mov_reg_A0(1, R_ESP);
2434
        else
2435
            gen_stack_update(s, (-2) << s->dflag);
2436
    }
2437
}
2438

    
2439
/* two step pop is necessary for precise exceptions */
2440
static void gen_pop_T0(DisasContext *s)
2441
{
2442
#ifdef TARGET_X86_64
2443
    if (CODE64(s)) {
2444
        gen_op_movq_A0_reg(R_ESP);
2445
        gen_op_ld_T0_A0((s->dflag ? OT_QUAD : OT_WORD) + s->mem_index);
2446
    } else
2447
#endif
2448
    {
2449
        gen_op_movl_A0_reg(R_ESP);
2450
        if (s->ss32) {
2451
            if (s->addseg)
2452
                gen_op_addl_A0_seg(R_SS);
2453
        } else {
2454
            gen_op_andl_A0_ffff();
2455
            gen_op_addl_A0_seg(R_SS);
2456
        }
2457
        gen_op_ld_T0_A0(s->dflag + 1 + s->mem_index);
2458
    }
2459
}
2460

    
2461
static void gen_pop_update(DisasContext *s)
2462
{
2463
#ifdef TARGET_X86_64
2464
    if (CODE64(s) && s->dflag) {
2465
        gen_stack_update(s, 8);
2466
    } else
2467
#endif
2468
    {
2469
        gen_stack_update(s, 2 << s->dflag);
2470
    }
2471
}
2472

    
2473
static void gen_stack_A0(DisasContext *s)
2474
{
2475
    gen_op_movl_A0_reg(R_ESP);
2476
    if (!s->ss32)
2477
        gen_op_andl_A0_ffff();
2478
    tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2479
    if (s->addseg)
2480
        gen_op_addl_A0_seg(R_SS);
2481
}
2482

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

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

    
2524
static void gen_enter(DisasContext *s, int esp_addend, int level)
2525
{
2526
    int ot, opsize;
2527

    
2528
    level &= 0x1f;
2529
#ifdef TARGET_X86_64
2530
    if (CODE64(s)) {
2531
        ot = s->dflag ? OT_QUAD : OT_WORD;
2532
        opsize = 1 << ot;
2533

    
2534
        gen_op_movl_A0_reg(R_ESP);
2535
        gen_op_addq_A0_im(-opsize);
2536
        tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2537

    
2538
        /* push bp */
2539
        gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
2540
        gen_op_st_T0_A0(ot + s->mem_index);
2541
        if (level) {
2542
            /* XXX: must save state */
2543
            tcg_gen_helper_0_3(helper_enter64_level,
2544
                               tcg_const_i32(level),
2545
                               tcg_const_i32((ot == OT_QUAD)),
2546
                               cpu_T[1]);
2547
        }
2548
        gen_op_mov_reg_T1(ot, R_EBP);
2549
        tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2550
        gen_op_mov_reg_T1(OT_QUAD, R_ESP);
2551
    } else
2552
#endif
2553
    {
2554
        ot = s->dflag + OT_WORD;
2555
        opsize = 2 << s->dflag;
2556

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

    
2580
static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2581
{
2582
    if (s->cc_op != CC_OP_DYNAMIC)
2583
        gen_op_set_cc_op(s->cc_op);
2584
    gen_jmp_im(cur_eip);
2585
    tcg_gen_helper_0_1(helper_raise_exception, tcg_const_i32(trapno));
2586
    s->is_jmp = 3;
2587
}
2588

    
2589
/* an interrupt is different from an exception because of the
2590
   privilege checks */
2591
static void gen_interrupt(DisasContext *s, int intno,
2592
                          target_ulong cur_eip, target_ulong next_eip)
2593
{
2594
    if (s->cc_op != CC_OP_DYNAMIC)
2595
        gen_op_set_cc_op(s->cc_op);
2596
    gen_jmp_im(cur_eip);
2597
    tcg_gen_helper_0_2(helper_raise_interrupt, 
2598
                       tcg_const_i32(intno), 
2599
                       tcg_const_i32(next_eip - cur_eip));
2600
    s->is_jmp = 3;
2601
}
2602

    
2603
static void gen_debug(DisasContext *s, target_ulong cur_eip)
2604
{
2605
    if (s->cc_op != CC_OP_DYNAMIC)
2606
        gen_op_set_cc_op(s->cc_op);
2607
    gen_jmp_im(cur_eip);
2608
    tcg_gen_helper_0_0(helper_debug);
2609
    s->is_jmp = 3;
2610
}
2611

    
2612
/* generate a generic end of block. Trace exception is also generated
2613
   if needed */
2614
static void gen_eob(DisasContext *s)
2615
{
2616
    if (s->cc_op != CC_OP_DYNAMIC)
2617
        gen_op_set_cc_op(s->cc_op);
2618
    if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
2619
        tcg_gen_helper_0_0(helper_reset_inhibit_irq);
2620
    }
2621
    if (s->singlestep_enabled) {
2622
        tcg_gen_helper_0_0(helper_debug);
2623
    } else if (s->tf) {
2624
        tcg_gen_helper_0_0(helper_single_step);
2625
    } else {
2626
        tcg_gen_exit_tb(0);
2627
    }
2628
    s->is_jmp = 3;
2629
}
2630

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

    
2648
static void gen_jmp(DisasContext *s, target_ulong eip)
2649
{
2650
    gen_jmp_tb(s, eip, 0);
2651
}
2652

    
2653
static inline void gen_ldq_env_A0(int idx, int offset)
2654
{
2655
    int mem_index = (idx >> 2) - 1;
2656
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2657
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
2658
}
2659

    
2660
static inline void gen_stq_env_A0(int idx, int offset)
2661
{
2662
    int mem_index = (idx >> 2) - 1;
2663
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
2664
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2665
}
2666

    
2667
static inline void gen_ldo_env_A0(int idx, int offset)
2668
{
2669
    int mem_index = (idx >> 2) - 1;
2670
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2671
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2672
    tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2673
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2674
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2675
}
2676

    
2677
static inline void gen_sto_env_A0(int idx, int offset)
2678
{
2679
    int mem_index = (idx >> 2) - 1;
2680
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2681
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2682
    tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2683
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2684
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2685
}
2686

    
2687
static inline void gen_op_movo(int d_offset, int s_offset)
2688
{
2689
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2690
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2691
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + 8);
2692
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + 8);
2693
}
2694

    
2695
static inline void gen_op_movq(int d_offset, int s_offset)
2696
{
2697
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2698
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2699
}
2700

    
2701
static inline void gen_op_movl(int d_offset, int s_offset)
2702
{
2703
    tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
2704
    tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
2705
}
2706

    
2707
static inline void gen_op_movq_env_0(int d_offset)
2708
{
2709
    tcg_gen_movi_i64(cpu_tmp1_i64, 0);
2710
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2711
}
2712

    
2713
#define SSE_SPECIAL ((void *)1)
2714
#define SSE_DUMMY ((void *)2)
2715

    
2716
#define MMX_OP2(x) { helper_ ## x ## _mmx, helper_ ## x ## _xmm }
2717
#define SSE_FOP(x) { helper_ ## x ## ps, helper_ ## x ## pd, \
2718
                     helper_ ## x ## ss, helper_ ## x ## sd, }
2719

    
2720
static void *sse_op_table1[256][4] = {
2721
    /* 3DNow! extensions */
2722
    [0x0e] = { SSE_DUMMY }, /* femms */
2723
    [0x0f] = { SSE_DUMMY }, /* pf... */
2724
    /* pure SSE operations */
2725
    [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2726
    [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2727
    [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2728
    [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
2729
    [0x14] = { helper_punpckldq_xmm, helper_punpcklqdq_xmm },
2730
    [0x15] = { helper_punpckhdq_xmm, helper_punpckhqdq_xmm },
2731
    [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */
2732
    [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */
2733

    
2734
    [0x28] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2735
    [0x29] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2736
    [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2737
    [0x2b] = { SSE_SPECIAL, SSE_SPECIAL },  /* movntps, movntpd */
2738
    [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2739
    [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2740
    [0x2e] = { helper_ucomiss, helper_ucomisd },
2741
    [0x2f] = { helper_comiss, helper_comisd },
2742
    [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2743
    [0x51] = SSE_FOP(sqrt),
2744
    [0x52] = { helper_rsqrtps, NULL, helper_rsqrtss, NULL },
2745
    [0x53] = { helper_rcpps, NULL, helper_rcpss, NULL },
2746
    [0x54] = { helper_pand_xmm, helper_pand_xmm }, /* andps, andpd */
2747
    [0x55] = { helper_pandn_xmm, helper_pandn_xmm }, /* andnps, andnpd */
2748
    [0x56] = { helper_por_xmm, helper_por_xmm }, /* orps, orpd */
2749
    [0x57] = { helper_pxor_xmm, helper_pxor_xmm }, /* xorps, xorpd */
2750
    [0x58] = SSE_FOP(add),
2751
    [0x59] = SSE_FOP(mul),
2752
    [0x5a] = { helper_cvtps2pd, helper_cvtpd2ps,
2753
               helper_cvtss2sd, helper_cvtsd2ss },
2754
    [0x5b] = { helper_cvtdq2ps, helper_cvtps2dq, helper_cvttps2dq },
2755
    [0x5c] = SSE_FOP(sub),
2756
    [0x5d] = SSE_FOP(min),
2757
    [0x5e] = SSE_FOP(div),
2758
    [0x5f] = SSE_FOP(max),
2759

    
2760
    [0xc2] = SSE_FOP(cmpeq),
2761
    [0xc6] = { helper_shufps, helper_shufpd },
2762

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

    
2846
static void *sse_op_table2[3 * 8][2] = {
2847
    [0 + 2] = MMX_OP2(psrlw),
2848
    [0 + 4] = MMX_OP2(psraw),
2849
    [0 + 6] = MMX_OP2(psllw),
2850
    [8 + 2] = MMX_OP2(psrld),
2851
    [8 + 4] = MMX_OP2(psrad),
2852
    [8 + 6] = MMX_OP2(pslld),
2853
    [16 + 2] = MMX_OP2(psrlq),
2854
    [16 + 3] = { NULL, helper_psrldq_xmm },
2855
    [16 + 6] = MMX_OP2(psllq),
2856
    [16 + 7] = { NULL, helper_pslldq_xmm },
2857
};
2858

    
2859
static void *sse_op_table3[4 * 3] = {
2860
    helper_cvtsi2ss,
2861
    helper_cvtsi2sd,
2862
    X86_64_ONLY(helper_cvtsq2ss),
2863
    X86_64_ONLY(helper_cvtsq2sd),
2864

    
2865
    helper_cvttss2si,
2866
    helper_cvttsd2si,
2867
    X86_64_ONLY(helper_cvttss2sq),
2868
    X86_64_ONLY(helper_cvttsd2sq),
2869

    
2870
    helper_cvtss2si,
2871
    helper_cvtsd2si,
2872
    X86_64_ONLY(helper_cvtss2sq),
2873
    X86_64_ONLY(helper_cvtsd2sq),
2874
};
2875

    
2876
static void *sse_op_table4[8][4] = {
2877
    SSE_FOP(cmpeq),
2878
    SSE_FOP(cmplt),
2879
    SSE_FOP(cmple),
2880
    SSE_FOP(cmpunord),
2881
    SSE_FOP(cmpneq),
2882
    SSE_FOP(cmpnlt),
2883
    SSE_FOP(cmpnle),
2884
    SSE_FOP(cmpord),
2885
};
2886

    
2887
static void *sse_op_table5[256] = {
2888
    [0x0c] = helper_pi2fw,
2889
    [0x0d] = helper_pi2fd,
2890
    [0x1c] = helper_pf2iw,
2891
    [0x1d] = helper_pf2id,
2892
    [0x8a] = helper_pfnacc,
2893
    [0x8e] = helper_pfpnacc,
2894
    [0x90] = helper_pfcmpge,
2895
    [0x94] = helper_pfmin,
2896
    [0x96] = helper_pfrcp,
2897
    [0x97] = helper_pfrsqrt,
2898
    [0x9a] = helper_pfsub,
2899
    [0x9e] = helper_pfadd,
2900
    [0xa0] = helper_pfcmpgt,
2901
    [0xa4] = helper_pfmax,
2902
    [0xa6] = helper_movq, /* pfrcpit1; no need to actually increase precision */
2903
    [0xa7] = helper_movq, /* pfrsqit1 */
2904
    [0xaa] = helper_pfsubr,
2905
    [0xae] = helper_pfacc,
2906
    [0xb0] = helper_pfcmpeq,
2907
    [0xb4] = helper_pfmul,
2908
    [0xb6] = helper_movq, /* pfrcpit2 */
2909
    [0xb7] = helper_pmulhrw_mmx,
2910
    [0xbb] = helper_pswapd,
2911
    [0xbf] = helper_pavgb_mmx /* pavgusb */
2912
};
2913

    
2914
static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
2915
{
2916
    int b1, op1_offset, op2_offset, is_xmm, val, ot;
2917
    int modrm, mod, rm, reg, reg_addr, offset_addr;
2918
    void *sse_op2;
2919

    
2920
    b &= 0xff;
2921
    if (s->prefix & PREFIX_DATA)
2922
        b1 = 1;
2923
    else if (s->prefix & PREFIX_REPZ)
2924
        b1 = 2;
2925
    else if (s->prefix & PREFIX_REPNZ)
2926
        b1 = 3;
2927
    else
2928
        b1 = 0;
2929
    sse_op2 = sse_op_table1[b][b1];
2930
    if (!sse_op2)
2931
        goto illegal_op;
2932
    if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
2933
        is_xmm = 1;
2934
    } else {
2935
        if (b1 == 0) {
2936
            /* MMX case */
2937
            is_xmm = 0;
2938
        } else {
2939
            is_xmm = 1;
2940
        }
2941
    }
2942
    /* simple MMX/SSE operation */
2943
    if (s->flags & HF_TS_MASK) {
2944
        gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
2945
        return;
2946
    }
2947
    if (s->flags & HF_EM_MASK) {
2948
    illegal_op:
2949
        gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
2950
        return;
2951
    }
2952
    if (is_xmm && !(s->flags & HF_OSFXSR_MASK))
2953
        goto illegal_op;
2954
    if (b == 0x0e) {
2955
        if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
2956
            goto illegal_op;
2957
        /* femms */
2958
        tcg_gen_helper_0_0(helper_emms);
2959
        return;
2960
    }
2961
    if (b == 0x77) {
2962
        /* emms */
2963
        tcg_gen_helper_0_0(helper_emms);
2964
        return;
2965
    }
2966
    /* prepare MMX state (XXX: optimize by storing fptt and fptags in
2967
       the static cpu state) */
2968
    if (!is_xmm) {
2969
        tcg_gen_helper_0_0(helper_enter_mmx);
2970
    }
2971

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

    
3564
            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3565
            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3566
            tcg_gen_helper_0_3(sse_op2, cpu_ptr0, cpu_ptr1, cpu_A0);
3567
            break;
3568
        default:
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_2(sse_op2, cpu_ptr0, cpu_ptr1);
3572
            break;
3573
        }
3574
        if (b == 0x2e || b == 0x2f) {
3575
            s->cc_op = CC_OP_EFLAGS;
3576
        }
3577
    }
3578
}
3579

    
3580
/* convert one instruction. s->is_jmp is set if the translation must
3581
   be stopped. Return the next pc value */
3582
static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
3583
{
3584
    int b, prefixes, aflag, dflag;
3585
    int shift, ot;
3586
    int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
3587
    target_ulong next_eip, tval;
3588
    int rex_w, rex_r;
3589

    
3590
    if (unlikely(loglevel & CPU_LOG_TB_OP))
3591
        tcg_gen_debug_insn_start(pc_start);
3592
    s->pc = pc_start;
3593
    prefixes = 0;
3594
    aflag = s->code32;
3595
    dflag = s->code32;
3596
    s->override = -1;
3597
    rex_w = -1;
3598
    rex_r = 0;
3599
#ifdef TARGET_X86_64
3600
    s->rex_x = 0;
3601
    s->rex_b = 0;
3602
    x86_64_hregs = 0;
3603
#endif
3604
    s->rip_offset = 0; /* for relative ip address */
3605
 next_byte:
3606
    b = ldub_code(s->pc);
3607
    s->pc++;
3608
    /* check prefixes */
3609
#ifdef TARGET_X86_64
3610
    if (CODE64(s)) {
3611
        switch (b) {
3612
        case 0xf3:
3613
            prefixes |= PREFIX_REPZ;
3614
            goto next_byte;
3615
        case 0xf2:
3616
            prefixes |= PREFIX_REPNZ;
3617
            goto next_byte;
3618
        case 0xf0:
3619
            prefixes |= PREFIX_LOCK;
3620
            goto next_byte;
3621
        case 0x2e:
3622
            s->override = R_CS;
3623
            goto next_byte;
3624
        case 0x36:
3625
            s->override = R_SS;
3626
            goto next_byte;
3627
        case 0x3e:
3628
            s->override = R_DS;
3629
            goto next_byte;
3630
        case 0x26:
3631
            s->override = R_ES;
3632
            goto next_byte;
3633
        case 0x64:
3634
            s->override = R_FS;
3635
            goto next_byte;
3636
        case 0x65:
3637
            s->override = R_GS;
3638
            goto next_byte;
3639
        case 0x66:
3640
            prefixes |= PREFIX_DATA;
3641
            goto next_byte;
3642
        case 0x67:
3643
            prefixes |= PREFIX_ADR;
3644
            goto next_byte;
3645
        case 0x40 ... 0x4f:
3646
            /* REX prefix */
3647
            rex_w = (b >> 3) & 1;
3648
            rex_r = (b & 0x4) << 1;
3649
            s->rex_x = (b & 0x2) << 2;
3650
            REX_B(s) = (b & 0x1) << 3;
3651
            x86_64_hregs = 1; /* select uniform byte register addressing */
3652
            goto next_byte;
3653
        }
3654
        if (rex_w == 1) {
3655
            /* 0x66 is ignored if rex.w is set */
3656
            dflag = 2;
3657
        } else {
3658
            if (prefixes & PREFIX_DATA)
3659
                dflag ^= 1;
3660
        }
3661
        if (!(prefixes & PREFIX_ADR))
3662
            aflag = 2;
3663
    } else
3664
#endif
3665
    {
3666
        switch (b) {
3667
        case 0xf3:
3668
            prefixes |= PREFIX_REPZ;
3669
            goto next_byte;
3670
        case 0xf2:
3671
            prefixes |= PREFIX_REPNZ;
3672
            goto next_byte;
3673
        case 0xf0:
3674
            prefixes |= PREFIX_LOCK;
3675
            goto next_byte;
3676
        case 0x2e:
3677
            s->override = R_CS;
3678
            goto next_byte;
3679
        case 0x36:
3680
            s->override = R_SS;
3681
            goto next_byte;
3682
        case 0x3e:
3683
            s->override = R_DS;
3684
            goto next_byte;
3685
        case 0x26:
3686
            s->override = R_ES;
3687
            goto next_byte;
3688
        case 0x64:
3689
            s->override = R_FS;
3690
            goto next_byte;
3691
        case 0x65:
3692
            s->override = R_GS;
3693
            goto next_byte;
3694
        case 0x66:
3695
            prefixes |= PREFIX_DATA;
3696
            goto next_byte;
3697
        case 0x67:
3698
            prefixes |= PREFIX_ADR;
3699
            goto next_byte;
3700
        }
3701
        if (prefixes & PREFIX_DATA)
3702
            dflag ^= 1;
3703
        if (prefixes & PREFIX_ADR)
3704
            aflag ^= 1;
3705
    }
3706

    
3707
    s->prefix = prefixes;
3708
    s->aflag = aflag;
3709
    s->dflag = dflag;
3710

    
3711
    /* lock generation */
3712
    if (prefixes & PREFIX_LOCK)
3713
        tcg_gen_helper_0_0(helper_lock);
3714

    
3715
    /* now check op code */
3716
 reswitch:
3717
    switch(b) {
3718
    case 0x0f:
3719
        /**************************/
3720
        /* extended op code */
3721
        b = ldub_code(s->pc++) | 0x100;
3722
        goto reswitch;
3723

    
3724
        /**************************/
3725
        /* arith & logic */
3726
    case 0x00 ... 0x05:
3727
    case 0x08 ... 0x0d:
3728
    case 0x10 ... 0x15:
3729
    case 0x18 ... 0x1d:
3730
    case 0x20 ... 0x25:
3731
    case 0x28 ... 0x2d:
3732
    case 0x30 ... 0x35:
3733
    case 0x38 ... 0x3d:
3734
        {
3735
            int op, f, val;
3736
            op = (b >> 3) & 7;
3737
            f = (b >> 1) & 3;
3738

    
3739
            if ((b & 1) == 0)
3740
                ot = OT_BYTE;
3741
            else
3742
                ot = dflag + OT_WORD;
3743

    
3744
            switch(f) {
3745
            case 0: /* OP Ev, Gv */
3746
                modrm = ldub_code(s->pc++);
3747
                reg = ((modrm >> 3) & 7) | rex_r;
3748
                mod = (modrm >> 6) & 3;
3749
                rm = (modrm & 7) | REX_B(s);
3750
                if (mod != 3) {
3751
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3752
                    opreg = OR_TMP0;
3753
                } else if (op == OP_XORL && rm == reg) {
3754
                xor_zero:
3755
                    /* xor reg, reg optimisation */
3756
                    gen_op_movl_T0_0();
3757
                    s->cc_op = CC_OP_LOGICB + ot;
3758
                    gen_op_mov_reg_T0(ot, reg);
3759
                    gen_op_update1_cc();
3760
                    break;
3761
                } else {
3762
                    opreg = rm;
3763
                }
3764
                gen_op_mov_TN_reg(ot, 1, reg);
3765
                gen_op(s, op, ot, opreg);
3766
                break;
3767
            case 1: /* OP Gv, Ev */
3768
                modrm = ldub_code(s->pc++);
3769
                mod = (modrm >> 6) & 3;
3770
                reg = ((modrm >> 3) & 7) | rex_r;
3771
                rm = (modrm & 7) | REX_B(s);
3772
                if (mod != 3) {
3773
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3774
                    gen_op_ld_T1_A0(ot + s->mem_index);
3775
                } else if (op == OP_XORL && rm == reg) {
3776
                    goto xor_zero;
3777
                } else {
3778
                    gen_op_mov_TN_reg(ot, 1, rm);
3779
                }
3780
                gen_op(s, op, ot, reg);
3781
                break;
3782
            case 2: /* OP A, Iv */
3783
                val = insn_get(s, ot);
3784
                gen_op_movl_T1_im(val);
3785
                gen_op(s, op, ot, OR_EAX);
3786
                break;
3787
            }
3788
        }
3789
        break;
3790

    
3791
    case 0x80: /* GRP1 */
3792
    case 0x81:
3793
    case 0x82:
3794
    case 0x83:
3795
        {
3796
            int val;
3797

    
3798
            if ((b & 1) == 0)
3799
                ot = OT_BYTE;
3800
            else
3801
                ot = dflag + OT_WORD;
3802

    
3803
            modrm = ldub_code(s->pc++);
3804
            mod = (modrm >> 6) & 3;
3805
            rm = (modrm & 7) | REX_B(s);
3806
            op = (modrm >> 3) & 7;
3807

    
3808
            if (mod != 3) {
3809
                if (b == 0x83)
3810
                    s->rip_offset = 1;
3811
                else
3812
                    s->rip_offset = insn_const_size(ot);
3813
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3814
                opreg = OR_TMP0;
3815
            } else {
3816
                opreg = rm;
3817
            }
3818

    
3819
            switch(b) {
3820
            default:
3821
            case 0x80:
3822
            case 0x81:
3823
            case 0x82:
3824
                val = insn_get(s, ot);
3825
                break;
3826
            case 0x83:
3827
                val = (int8_t)insn_get(s, OT_BYTE);
3828
                break;
3829
            }
3830
            gen_op_movl_T1_im(val);
3831
            gen_op(s, op, ot, opreg);
3832
        }
3833
        break;
3834

    
3835
        /**************************/
3836
        /* inc, dec, and other misc arith */
3837
    case 0x40 ... 0x47: /* inc Gv */
3838
        ot = dflag ? OT_LONG : OT_WORD;
3839
        gen_inc(s, ot, OR_EAX + (b & 7), 1);
3840
        break;
3841
    case 0x48 ... 0x4f: /* dec Gv */
3842
        ot = dflag ? OT_LONG : OT_WORD;
3843
        gen_inc(s, ot, OR_EAX + (b & 7), -1);
3844
        break;
3845
    case 0xf6: /* GRP3 */
3846
    case 0xf7:
3847
        if ((b & 1) == 0)
3848
            ot = OT_BYTE;
3849
        else
3850
            ot = dflag + OT_WORD;
3851

    
3852
        modrm = ldub_code(s->pc++);
3853
        mod = (modrm >> 6) & 3;
3854
        rm = (modrm & 7) | REX_B(s);
3855
        op = (modrm >> 3) & 7;
3856
        if (mod != 3) {
3857
            if (op == 0)
3858
                s->rip_offset = insn_const_size(ot);
3859
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3860
            gen_op_ld_T0_A0(ot + s->mem_index);
3861
        } else {
3862
            gen_op_mov_TN_reg(ot, 0, rm);
3863
        }
3864

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

    
4077
    case 0xfe: /* GRP4 */
4078
    case 0xff: /* GRP5 */
4079
        if ((b & 1) == 0)
4080
            ot = OT_BYTE;
4081
        else
4082
            ot = dflag + OT_WORD;
4083

    
4084
        modrm = ldub_code(s->pc++);
4085
        mod = (modrm >> 6) & 3;
4086
        rm = (modrm & 7) | REX_B(s);
4087
        op = (modrm >> 3) & 7;
4088
        if (op >= 2 && b == 0xfe) {
4089
            goto illegal_op;
4090
        }
4091
        if (CODE64(s)) {
4092
            if (op == 2 || op == 4) {
4093
                /* operand size for jumps is 64 bit */
4094
                ot = OT_QUAD;
4095
            } else if (op == 3 || op == 5) {
4096
                /* for call calls, the operand is 16 or 32 bit, even
4097
                   in long mode */
4098
                ot = dflag ? OT_LONG : OT_WORD;
4099
            } else if (op == 6) {
4100
                /* default push size is 64 bit */
4101
                ot = dflag ? OT_QUAD : OT_WORD;
4102
            }
4103
        }
4104
        if (mod != 3) {
4105
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4106
            if (op >= 2 && op != 3 && op != 5)
4107
                gen_op_ld_T0_A0(ot + s->mem_index);
4108
        } else {
4109
            gen_op_mov_TN_reg(ot, 0, rm);
4110
        }
4111

    
4112
        switch(op) {
4113
        case 0: /* inc Ev */
4114
            if (mod != 3)
4115
                opreg = OR_TMP0;
4116
            else
4117
                opreg = rm;
4118
            gen_inc(s, ot, opreg, 1);
4119
            break;
4120
        case 1: /* dec Ev */
4121
            if (mod != 3)
4122
                opreg = OR_TMP0;
4123
            else
4124
                opreg = rm;
4125
            gen_inc(s, ot, opreg, -1);
4126
            break;
4127
        case 2: /* call Ev */
4128
            /* XXX: optimize if memory (no 'and' is necessary) */
4129
            if (s->dflag == 0)
4130
                gen_op_andl_T0_ffff();
4131
            next_eip = s->pc - s->cs_base;
4132
            gen_movtl_T1_im(next_eip);
4133
            gen_push_T1(s);
4134
            gen_op_jmp_T0();
4135
            gen_eob(s);
4136
            break;
4137
        case 3: /* lcall Ev */
4138
            gen_op_ld_T1_A0(ot + s->mem_index);
4139
            gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4140
            gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
4141
        do_lcall:
4142
            if (s->pe && !s->vm86) {
4143
                if (s->cc_op != CC_OP_DYNAMIC)
4144
                    gen_op_set_cc_op(s->cc_op);
4145
                gen_jmp_im(pc_start - s->cs_base);
4146
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4147
                tcg_gen_helper_0_4(helper_lcall_protected,
4148
                                   cpu_tmp2_i32, cpu_T[1],
4149
                                   tcg_const_i32(dflag), 
4150
                                   tcg_const_i32(s->pc - pc_start));
4151
            } else {
4152
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4153
                tcg_gen_helper_0_4(helper_lcall_real,
4154
                                   cpu_tmp2_i32, cpu_T[1],
4155
                                   tcg_const_i32(dflag), 
4156
                                   tcg_const_i32(s->pc - s->cs_base));
4157
            }
4158
            gen_eob(s);
4159
            break;
4160
        case 4: /* jmp Ev */
4161
            if (s->dflag == 0)
4162
                gen_op_andl_T0_ffff();
4163
            gen_op_jmp_T0();
4164
            gen_eob(s);
4165
            break;
4166
        case 5: /* ljmp Ev */
4167
            gen_op_ld_T1_A0(ot + s->mem_index);
4168
            gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4169
            gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
4170
        do_ljmp:
4171
            if (s->pe && !s->vm86) {
4172
                if (s->cc_op != CC_OP_DYNAMIC)
4173
                    gen_op_set_cc_op(s->cc_op);
4174
                gen_jmp_im(pc_start - s->cs_base);
4175
                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4176
                tcg_gen_helper_0_3(helper_ljmp_protected,
4177
                                   cpu_tmp2_i32,
4178
                                   cpu_T[1],
4179
                                   tcg_const_i32(s->pc - pc_start));
4180
            } else {
4181
                gen_op_movl_seg_T0_vm(R_CS);
4182
                gen_op_movl_T0_T1();
4183
                gen_op_jmp_T0();
4184
            }
4185
            gen_eob(s);
4186
            break;
4187
        case 6: /* push Ev */
4188
            gen_push_T0(s);
4189
            break;
4190
        default:
4191
            goto illegal_op;
4192
        }
4193
        break;
4194

    
4195
    case 0x84: /* test Ev, Gv */
4196
    case 0x85:
4197
        if ((b & 1) == 0)
4198
            ot = OT_BYTE;
4199
        else
4200
            ot = dflag + OT_WORD;
4201

    
4202
        modrm = ldub_code(s->pc++);
4203
        mod = (modrm >> 6) & 3;
4204
        rm = (modrm & 7) | REX_B(s);
4205
        reg = ((modrm >> 3) & 7) | rex_r;
4206

    
4207
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
4208
        gen_op_mov_TN_reg(ot, 1, reg);
4209
        gen_op_testl_T0_T1_cc();
4210
        s->cc_op = CC_OP_LOGICB + ot;
4211
        break;
4212

    
4213
    case 0xa8: /* test eAX, Iv */
4214
    case 0xa9:
4215
        if ((b & 1) == 0)
4216
            ot = OT_BYTE;
4217
        else
4218
            ot = dflag + OT_WORD;
4219
        val = insn_get(s, ot);
4220

    
4221
        gen_op_mov_TN_reg(ot, 0, OR_EAX);
4222
        gen_op_movl_T1_im(val);
4223
        gen_op_testl_T0_T1_cc();
4224
        s->cc_op = CC_OP_LOGICB + ot;
4225
        break;
4226

    
4227
    case 0x98: /* CWDE/CBW */
4228
#ifdef TARGET_X86_64
4229
        if (dflag == 2) {
4230
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
4231
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4232
            gen_op_mov_reg_T0(OT_QUAD, R_EAX);
4233
        } else
4234
#endif
4235
        if (dflag == 1) {
4236
            gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
4237
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4238
            gen_op_mov_reg_T0(OT_LONG, R_EAX);
4239
        } else {
4240
            gen_op_mov_TN_reg(OT_BYTE, 0, R_EAX);
4241
            tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
4242
            gen_op_mov_reg_T0(OT_WORD, R_EAX);
4243
        }
4244
        break;
4245
    case 0x99: /* CDQ/CWD */
4246
#ifdef TARGET_X86_64
4247
        if (dflag == 2) {
4248
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
4249
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 63);
4250
            gen_op_mov_reg_T0(OT_QUAD, R_EDX);
4251
        } else
4252
#endif
4253
        if (dflag == 1) {
4254
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
4255
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4256
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 31);
4257
            gen_op_mov_reg_T0(OT_LONG, R_EDX);
4258
        } else {
4259
            gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
4260
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4261
            tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 15);
4262
            gen_op_mov_reg_T0(OT_WORD, R_EDX);
4263
        }
4264
        break;
4265
    case 0x1af: /* imul Gv, Ev */
4266
    case 0x69: /* imul Gv, Ev, I */
4267
    case 0x6b:
4268
        ot = dflag + OT_WORD;
4269
        modrm = ldub_code(s->pc++);
4270
        reg = ((modrm >> 3) & 7) | rex_r;
4271
        if (b == 0x69)
4272
            s->rip_offset = insn_const_size(ot);
4273
        else if (b == 0x6b)
4274
            s->rip_offset = 1;
4275
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
4276
        if (b == 0x69) {
4277
            val = insn_get(s, ot);
4278
            gen_op_movl_T1_im(val);
4279
        } else if (b == 0x6b) {
4280
            val = (int8_t)insn_get(s, OT_BYTE);
4281
            gen_op_movl_T1_im(val);
4282
        } else {
4283
            gen_op_mov_TN_reg(ot, 1, reg);
4284
        }
4285

    
4286
#ifdef TARGET_X86_64
4287
        if (ot == OT_QUAD) {
4288
            tcg_gen_helper_1_2(helper_imulq_T0_T1, cpu_T[0], cpu_T[0], cpu_T[1]);
4289
        } else
4290
#endif
4291
        if (ot == OT_LONG) {
4292
#ifdef TARGET_X86_64
4293
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4294
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
4295
                tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4296
                tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4297
                tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
4298
                tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4299
#else
4300
                {
4301
                    TCGv t0, t1;
4302
                    t0 = tcg_temp_new(TCG_TYPE_I64);
4303
                    t1 = tcg_temp_new(TCG_TYPE_I64);
4304
                    tcg_gen_ext_i32_i64(t0, cpu_T[0]);
4305
                    tcg_gen_ext_i32_i64(t1, cpu_T[1]);
4306
                    tcg_gen_mul_i64(t0, t0, t1);
4307
                    tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4308
                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4309
                    tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
4310
                    tcg_gen_shri_i64(t0, t0, 32);
4311
                    tcg_gen_trunc_i64_i32(cpu_T[1], t0);
4312
                    tcg_gen_sub_tl(cpu_cc_src, cpu_T[1], cpu_tmp0);
4313
                }
4314
#endif
4315
        } else {
4316
            tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4317
            tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
4318
            /* XXX: use 32 bit mul which could be faster */
4319
            tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4320
            tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4321
            tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
4322
            tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4323
        }
4324
        gen_op_mov_reg_T0(ot, reg);
4325
        s->cc_op = CC_OP_MULB + ot;
4326
        break;
4327
    case 0x1c0:
4328
    case 0x1c1: /* xadd Ev, Gv */
4329
        if ((b & 1) == 0)
4330
            ot = OT_BYTE;
4331
        else
4332
            ot = dflag + OT_WORD;
4333
        modrm = ldub_code(s->pc++);
4334
        reg = ((modrm >> 3) & 7) | rex_r;
4335
        mod = (modrm >> 6) & 3;
4336
        if (mod == 3) {
4337
            rm = (modrm & 7) | REX_B(s);
4338
            gen_op_mov_TN_reg(ot, 0, reg);
4339
            gen_op_mov_TN_reg(ot, 1, rm);
4340
            gen_op_addl_T0_T1();
4341
            gen_op_mov_reg_T1(ot, reg);
4342
            gen_op_mov_reg_T0(ot, rm);
4343
        } else {
4344
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4345
            gen_op_mov_TN_reg(ot, 0, reg);
4346
            gen_op_ld_T1_A0(ot + s->mem_index);
4347
            gen_op_addl_T0_T1();
4348
            gen_op_st_T0_A0(ot + s->mem_index);
4349
            gen_op_mov_reg_T1(ot, reg);
4350
        }
4351
        gen_op_update2_cc();
4352
        s->cc_op = CC_OP_ADDB + ot;
4353
        break;
4354
    case 0x1b0:
4355
    case 0x1b1: /* cmpxchg Ev, Gv */
4356
        {
4357
            int label1, label2;
4358
            TCGv t0, t1, t2, a0;
4359

    
4360
            if ((b & 1) == 0)
4361
                ot = OT_BYTE;
4362
            else
4363
                ot = dflag + OT_WORD;
4364
            modrm = ldub_code(s->pc++);
4365
            reg = ((modrm >> 3) & 7) | rex_r;
4366
            mod = (modrm >> 6) & 3;
4367
            t0 = tcg_temp_local_new(TCG_TYPE_TL);
4368
            t1 = tcg_temp_local_new(TCG_TYPE_TL);
4369
            t2 = tcg_temp_local_new(TCG_TYPE_TL);
4370
            a0 = tcg_temp_local_new(TCG_TYPE_TL);
4371
            gen_op_mov_v_reg(ot, t1, reg);
4372
            if (mod == 3) {
4373
                rm = (modrm & 7) | REX_B(s);
4374
                gen_op_mov_v_reg(ot, t0, rm);
4375
            } else {
4376
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4377
                tcg_gen_mov_tl(a0, cpu_A0);
4378
                gen_op_ld_v(ot + s->mem_index, t0, a0);
4379
                rm = 0; /* avoid warning */
4380
            }
4381
            label1 = gen_new_label();
4382
            tcg_gen_ld_tl(t2, cpu_env, offsetof(CPUState, regs[R_EAX]));
4383
            tcg_gen_sub_tl(t2, t2, t0);
4384
            gen_extu(ot, t2);
4385
            tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
4386
            if (mod == 3) {
4387
                label2 = gen_new_label();
4388
                gen_op_mov_reg_v(ot, R_EAX, t0);
4389
                tcg_gen_br(label2);
4390
                gen_set_label(label1);
4391
                gen_op_mov_reg_v(ot, rm, t1);
4392
                gen_set_label(label2);
4393
            } else {
4394
                tcg_gen_mov_tl(t1, t0);
4395
                gen_op_mov_reg_v(ot, R_EAX, t0);
4396
                gen_set_label(label1);
4397
                /* always store */
4398
                gen_op_st_v(ot + s->mem_index, t1, a0);
4399
            }
4400
            tcg_gen_mov_tl(cpu_cc_src, t0);
4401
            tcg_gen_mov_tl(cpu_cc_dst, t2);
4402
            s->cc_op = CC_OP_SUBB + ot;
4403
            tcg_temp_free(t0);
4404
            tcg_temp_free(t1);
4405
            tcg_temp_free(t2);
4406
            tcg_temp_free(a0);
4407
        }
4408
        break;
4409
    case 0x1c7: /* cmpxchg8b */
4410
        modrm = ldub_code(s->pc++);
4411
        mod = (modrm >> 6) & 3;
4412
        if ((mod == 3) || ((modrm & 0x38) != 0x8))
4413
            goto illegal_op;
4414
#ifdef TARGET_X86_64
4415
        if (dflag == 2) {
4416
            if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
4417
                goto illegal_op;
4418
            gen_jmp_im(pc_start - s->cs_base);
4419
            if (s->cc_op != CC_OP_DYNAMIC)
4420
                gen_op_set_cc_op(s->cc_op);
4421
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4422
            tcg_gen_helper_0_1(helper_cmpxchg16b, cpu_A0);
4423
        } else
4424
#endif        
4425
        {
4426
            if (!(s->cpuid_features & CPUID_CX8))
4427
                goto illegal_op;
4428
            gen_jmp_im(pc_start - s->cs_base);
4429
            if (s->cc_op != CC_OP_DYNAMIC)
4430
                gen_op_set_cc_op(s->cc_op);
4431
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4432
            tcg_gen_helper_0_1(helper_cmpxchg8b, cpu_A0);
4433
        }
4434
        s->cc_op = CC_OP_EFLAGS;
4435
        break;
4436

    
4437
        /**************************/
4438
        /* push/pop */
4439
    case 0x50 ... 0x57: /* push */
4440
        gen_op_mov_TN_reg(OT_LONG, 0, (b & 7) | REX_B(s));
4441
        gen_push_T0(s);
4442
        break;
4443
    case 0x58 ... 0x5f: /* pop */
4444
        if (CODE64(s)) {
4445
            ot = dflag ? OT_QUAD : OT_WORD;
4446
        } else {
4447
            ot = dflag + OT_WORD;
4448
        }
4449
        gen_pop_T0(s);
4450
        /* NOTE: order is important for pop %sp */
4451
        gen_pop_update(s);
4452
        gen_op_mov_reg_T0(ot, (b & 7) | REX_B(s));
4453
        break;
4454
    case 0x60: /* pusha */
4455
        if (CODE64(s))
4456
            goto illegal_op;
4457
        gen_pusha(s);
4458
        break;
4459
    case 0x61: /* popa */
4460
        if (CODE64(s))
4461
            goto illegal_op;
4462
        gen_popa(s);
4463
        break;
4464
    case 0x68: /* push Iv */
4465
    case 0x6a:
4466
        if (CODE64(s)) {
4467
            ot = dflag ? OT_QUAD : OT_WORD;
4468
        } else {
4469
            ot = dflag + OT_WORD;
4470
        }
4471
        if (b == 0x68)
4472
            val = insn_get(s, ot);
4473
        else
4474
            val = (int8_t)insn_get(s, OT_BYTE);
4475
        gen_op_movl_T0_im(val);
4476
        gen_push_T0(s);
4477
        break;
4478
    case 0x8f: /* pop Ev */
4479
        if (CODE64(s)) {
4480
            ot = dflag ? OT_QUAD : OT_WORD;
4481
        } else {
4482
            ot = dflag + OT_WORD;
4483
        }
4484
        modrm = ldub_code(s->pc++);
4485
        mod = (modrm >> 6) & 3;
4486
        gen_pop_T0(s);
4487
        if (mod == 3) {
4488
            /* NOTE: order is important for pop %sp */
4489
            gen_pop_update(s);
4490
            rm = (modrm & 7) | REX_B(s);
4491
            gen_op_mov_reg_T0(ot, rm);
4492
        } else {
4493
            /* NOTE: order is important too for MMU exceptions */
4494
            s->popl_esp_hack = 1 << ot;
4495
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
4496
            s->popl_esp_hack = 0;
4497
            gen_pop_update(s);
4498
        }
4499
        break;
4500
    case 0xc8: /* enter */
4501
        {
4502
            int level;
4503
            val = lduw_code(s->pc);
4504
            s->pc += 2;
4505
            level = ldub_code(s->pc++);
4506
            gen_enter(s, val, level);
4507
        }
4508
        break;
4509
    case 0xc9: /* leave */
4510
        /* XXX: exception not precise (ESP is updated before potential exception) */
4511
        if (CODE64(s)) {
4512
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EBP);
4513
            gen_op_mov_reg_T0(OT_QUAD, R_ESP);
4514
        } else if (s->ss32) {
4515
            gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
4516
            gen_op_mov_reg_T0(OT_LONG, R_ESP);
4517
        } else {
4518
            gen_op_mov_TN_reg(OT_WORD, 0, R_EBP);
4519
            gen_op_mov_reg_T0(OT_WORD, R_ESP);
4520
        }
4521
        gen_pop_T0(s);
4522
        if (CODE64(s)) {
4523
            ot = dflag ? OT_QUAD : OT_WORD;
4524
        } else {
4525
            ot = dflag + OT_WORD;
4526
        }
4527
        gen_op_mov_reg_T0(ot, R_EBP);
4528
        gen_pop_update(s);
4529
        break;
4530
    case 0x06: /* push es */
4531
    case 0x0e: /* push cs */
4532
    case 0x16: /* push ss */
4533
    case 0x1e: /* push ds */
4534
        if (CODE64(s))
4535
            goto illegal_op;
4536
        gen_op_movl_T0_seg(b >> 3);
4537
        gen_push_T0(s);
4538
        break;
4539
    case 0x1a0: /* push fs */
4540
    case 0x1a8: /* push gs */
4541
        gen_op_movl_T0_seg((b >> 3) & 7);
4542
        gen_push_T0(s);
4543
        break;
4544
    case 0x07: /* pop es */
4545
    case 0x17: /* pop ss */
4546
    case 0x1f: /* pop ds */
4547
        if (CODE64(s))
4548
            goto illegal_op;
4549
        reg = b >> 3;
4550
        gen_pop_T0(s);
4551
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
4552
        gen_pop_update(s);
4553
        if (reg == R_SS) {
4554
            /* if reg == SS, inhibit interrupts/trace. */
4555
            /* If several instructions disable interrupts, only the
4556
               _first_ does it */
4557
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
4558
                tcg_gen_helper_0_0(helper_set_inhibit_irq);
4559
            s->tf = 0;
4560
        }
4561
        if (s->is_jmp) {
4562
            gen_jmp_im(s->pc - s->cs_base);
4563
            gen_eob(s);
4564
        }
4565
        break;
4566
    case 0x1a1: /* pop fs */
4567
    case 0x1a9: /* pop gs */
4568
        gen_pop_T0(s);
4569
        gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
4570
        gen_pop_update(s);
4571
        if (s->is_jmp) {
4572
            gen_jmp_im(s->pc - s->cs_base);
4573
            gen_eob(s);
4574
        }
4575
        break;
4576

    
4577
        /**************************/
4578
        /* mov */
4579
    case 0x88:
4580
    case 0x89: /* mov Gv, Ev */
4581
        if ((b & 1) == 0)
4582
            ot = OT_BYTE;
4583
        else
4584
            ot = dflag + OT_WORD;
4585
        modrm = ldub_code(s->pc++);
4586
        reg = ((modrm >> 3) & 7) | rex_r;
4587

    
4588
        /* generate a generic store */
4589
        gen_ldst_modrm(s, modrm, ot, reg, 1);
4590
        break;
4591
    case 0xc6:
4592
    case 0xc7: /* mov Ev, Iv */
4593
        if ((b & 1) == 0)
4594
            ot = OT_BYTE;
4595
        else
4596
            ot = dflag + OT_WORD;
4597
        modrm = ldub_code(s->pc++);
4598
        mod = (modrm >> 6) & 3;
4599
        if (mod != 3) {
4600
            s->rip_offset = insn_const_size(ot);
4601
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4602
        }
4603
        val = insn_get(s, ot);
4604
        gen_op_movl_T0_im(val);
4605
        if (mod != 3)
4606
            gen_op_st_T0_A0(ot + s->mem_index);
4607
        else
4608
            gen_op_mov_reg_T0(ot, (modrm & 7) | REX_B(s));
4609
        break;
4610
    case 0x8a:
4611
    case 0x8b: /* mov Ev, Gv */
4612
        if ((b & 1) == 0)
4613
            ot = OT_BYTE;
4614
        else
4615
            ot = OT_WORD + dflag;
4616
        modrm = ldub_code(s->pc++);
4617
        reg = ((modrm >> 3) & 7) | rex_r;
4618

    
4619
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
4620
        gen_op_mov_reg_T0(ot, reg);
4621
        break;
4622
    case 0x8e: /* mov seg, Gv */
4623
        modrm = ldub_code(s->pc++);
4624
        reg = (modrm >> 3) & 7;
4625
        if (reg >= 6 || reg == R_CS)
4626
            goto illegal_op;
4627
        gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
4628
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
4629
        if (reg == R_SS) {
4630
            /* if reg == SS, inhibit interrupts/trace */
4631
            /* If several instructions disable interrupts, only the
4632
               _first_ does it */
4633
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
4634
                tcg_gen_helper_0_0(helper_set_inhibit_irq);
4635
            s->tf = 0;
4636
        }
4637
        if (s->is_jmp) {
4638
            gen_jmp_im(s->pc - s->cs_base);
4639
            gen_eob(s);
4640
        }
4641
        break;
4642
    case 0x8c: /* mov Gv, seg */
4643
        modrm = ldub_code(s->pc++);
4644
        reg = (modrm >> 3) & 7;
4645
        mod = (modrm >> 6) & 3;
4646
        if (reg >= 6)
4647
            goto illegal_op;
4648
        gen_op_movl_T0_seg(reg);
4649
        if (mod == 3)
4650
            ot = OT_WORD + dflag;
4651
        else
4652
            ot = OT_WORD;
4653
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
4654
        break;
4655

    
4656
    case 0x1b6: /* movzbS Gv, Eb */
4657
    case 0x1b7: /* movzwS Gv, Eb */
4658
    case 0x1be: /* movsbS Gv, Eb */
4659
    case 0x1bf: /* movswS Gv, Eb */
4660
        {
4661
            int d_ot;
4662
            /* d_ot is the size of destination */
4663
            d_ot = dflag + OT_WORD;
4664
            /* ot is the size of source */
4665
            ot = (b & 1) + OT_BYTE;
4666
            modrm = ldub_code(s->pc++);
4667
            reg = ((modrm >> 3) & 7) | rex_r;
4668
            mod = (modrm >> 6) & 3;
4669
            rm = (modrm & 7) | REX_B(s);
4670

    
4671
            if (mod == 3) {
4672
                gen_op_mov_TN_reg(ot, 0, rm);
4673
                switch(ot | (b & 8)) {
4674
                case OT_BYTE:
4675
                    tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
4676
                    break;
4677
                case OT_BYTE | 8:
4678
                    tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
4679
                    break;
4680
                case OT_WORD:
4681
                    tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
4682
                    break;
4683
                default:
4684
                case OT_WORD | 8:
4685
                    tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4686
                    break;
4687
                }
4688
                gen_op_mov_reg_T0(d_ot, reg);
4689
            } else {
4690
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4691
                if (b & 8) {
4692
                    gen_op_lds_T0_A0(ot + s->mem_index);
4693
                } else {
4694
                    gen_op_ldu_T0_A0(ot + s->mem_index);
4695
                }
4696
                gen_op_mov_reg_T0(d_ot, reg);
4697
            }
4698
        }
4699
        break;
4700

    
4701
    case 0x8d: /* lea */
4702
        ot = dflag + OT_WORD;
4703
        modrm = ldub_code(s->pc++);
4704
        mod = (modrm >> 6) & 3;
4705
        if (mod == 3)
4706
            goto illegal_op;
4707
        reg = ((modrm >> 3) & 7) | rex_r;
4708
        /* we must ensure that no segment is added */
4709
        s->override = -1;
4710
        val = s->addseg;
4711
        s->addseg = 0;
4712
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4713
        s->addseg = val;
4714
        gen_op_mov_reg_A0(ot - OT_WORD, reg);
4715
        break;
4716

    
4717
    case 0xa0: /* mov EAX, Ov */
4718
    case 0xa1:
4719
    case 0xa2: /* mov Ov, EAX */
4720
    case 0xa3:
4721
        {
4722
            target_ulong offset_addr;
4723

    
4724
            if ((b & 1) == 0)
4725
                ot = OT_BYTE;
4726
            else
4727
                ot = dflag + OT_WORD;
4728
#ifdef TARGET_X86_64
4729
            if (s->aflag == 2) {
4730
                offset_addr = ldq_code(s->pc);
4731
                s->pc += 8;
4732
                gen_op_movq_A0_im(offset_addr);
4733
            } else
4734
#endif
4735
            {
4736
                if (s->aflag) {
4737
                    offset_addr = insn_get(s, OT_LONG);
4738
                } else {
4739
                    offset_addr = insn_get(s, OT_WORD);
4740
                }
4741
                gen_op_movl_A0_im(offset_addr);
4742
            }
4743
            gen_add_A0_ds_seg(s);
4744
            if ((b & 2) == 0) {
4745
                gen_op_ld_T0_A0(ot + s->mem_index);
4746
                gen_op_mov_reg_T0(ot, R_EAX);
4747
            } else {
4748
                gen_op_mov_TN_reg(ot, 0, R_EAX);
4749
                gen_op_st_T0_A0(ot + s->mem_index);
4750
            }
4751
        }
4752
        break;
4753
    case 0xd7: /* xlat */
4754
#ifdef TARGET_X86_64
4755
        if (s->aflag == 2) {
4756
            gen_op_movq_A0_reg(R_EBX);
4757
            gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
4758
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
4759
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
4760
        } else
4761
#endif
4762
        {
4763
            gen_op_movl_A0_reg(R_EBX);
4764
            gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
4765
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
4766
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
4767
            if (s->aflag == 0)
4768
                gen_op_andl_A0_ffff();
4769
            else
4770
                tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
4771
        }
4772
        gen_add_A0_ds_seg(s);
4773
        gen_op_ldu_T0_A0(OT_BYTE + s->mem_index);
4774
        gen_op_mov_reg_T0(OT_BYTE, R_EAX);
4775
        break;
4776
    case 0xb0 ... 0xb7: /* mov R, Ib */
4777
        val = insn_get(s, OT_BYTE);
4778
        gen_op_movl_T0_im(val);
4779
        gen_op_mov_reg_T0(OT_BYTE, (b & 7) | REX_B(s));
4780
        break;
4781
    case 0xb8 ... 0xbf: /* mov R, Iv */
4782
#ifdef TARGET_X86_64
4783
        if (dflag == 2) {
4784
            uint64_t tmp;
4785
            /* 64 bit case */
4786
            tmp = ldq_code(s->pc);
4787
            s->pc += 8;
4788
            reg = (b & 7) | REX_B(s);
4789
            gen_movtl_T0_im(tmp);
4790
            gen_op_mov_reg_T0(OT_QUAD, reg);
4791
        } else
4792
#endif
4793
        {
4794
            ot = dflag ? OT_LONG : OT_WORD;
4795
            val = insn_get(s, ot);
4796
            reg = (b & 7) | REX_B(s);
4797
            gen_op_movl_T0_im(val);
4798
            gen_op_mov_reg_T0(ot, reg);
4799
        }
4800
        break;
4801

    
4802
    case 0x91 ... 0x97: /* xchg R, EAX */
4803
        ot = dflag + OT_WORD;
4804
        reg = (b & 7) | REX_B(s);
4805
        rm = R_EAX;
4806
        goto do_xchg_reg;
4807
    case 0x86:
4808
    case 0x87: /* xchg Ev, Gv */
4809
        if ((b & 1) == 0)
4810
            ot = OT_BYTE;
4811
        else
4812
            ot = dflag + OT_WORD;
4813
        modrm = ldub_code(s->pc++);
4814
        reg = ((modrm >> 3) & 7) | rex_r;
4815
        mod = (modrm >> 6) & 3;
4816
        if (mod == 3) {
4817
            rm = (modrm & 7) | REX_B(s);
4818
        do_xchg_reg:
4819
            gen_op_mov_TN_reg(ot, 0, reg);
4820
            gen_op_mov_TN_reg(ot, 1, rm);
4821
            gen_op_mov_reg_T0(ot, rm);
4822
            gen_op_mov_reg_T1(ot, reg);
4823
        } else {
4824
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4825
            gen_op_mov_TN_reg(ot, 0, reg);
4826
            /* for xchg, lock is implicit */
4827
            if (!(prefixes & PREFIX_LOCK))
4828
                tcg_gen_helper_0_0(helper_lock);
4829
            gen_op_ld_T1_A0(ot + s->mem_index);
4830
            gen_op_st_T0_A0(ot + s->mem_index);
4831
            if (!(prefixes & PREFIX_LOCK))
4832
                tcg_gen_helper_0_0(helper_unlock);
4833
            gen_op_mov_reg_T1(ot, reg);
4834
        }
4835
        break;
4836
    case 0xc4: /* les Gv */
4837
        if (CODE64(s))
4838
            goto illegal_op;
4839
        op = R_ES;
4840
        goto do_lxx;
4841
    case 0xc5: /* lds Gv */
4842
        if (CODE64(s))
4843
            goto illegal_op;
4844
        op = R_DS;
4845
        goto do_lxx;
4846
    case 0x1b2: /* lss Gv */
4847
        op = R_SS;
4848
        goto do_lxx;
4849
    case 0x1b4: /* lfs Gv */
4850
        op = R_FS;
4851
        goto do_lxx;
4852
    case 0x1b5: /* lgs Gv */
4853
        op = R_GS;
4854
    do_lxx:
4855
        ot = dflag ? OT_LONG : OT_WORD;
4856
        modrm = ldub_code(s->pc++);
4857
        reg = ((modrm >> 3) & 7) | rex_r;
4858
        mod = (modrm >> 6) & 3;
4859
        if (mod == 3)
4860
            goto illegal_op;
4861
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4862
        gen_op_ld_T1_A0(ot + s->mem_index);
4863
        gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4864
        /* load the segment first to handle exceptions properly */
4865
        gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
4866
        gen_movl_seg_T0(s, op, pc_start - s->cs_base);
4867
        /* then put the data */
4868
        gen_op_mov_reg_T1(ot, reg);
4869
        if (s->is_jmp) {
4870
            gen_jmp_im(s->pc - s->cs_base);
4871
            gen_eob(s);
4872
        }
4873
        break;
4874

    
4875
        /************************/
4876
        /* shifts */
4877
    case 0xc0:
4878
    case 0xc1:
4879
        /* shift Ev,Ib */
4880
        shift = 2;
4881
    grp2:
4882
        {
4883
            if ((b & 1) == 0)
4884
                ot = OT_BYTE;
4885
            else
4886
                ot = dflag + OT_WORD;
4887

    
4888
            modrm = ldub_code(s->pc++);
4889
            mod = (modrm >> 6) & 3;
4890
            op = (modrm >> 3) & 7;
4891

    
4892
            if (mod != 3) {
4893
                if (shift == 2) {
4894
                    s->rip_offset = 1;
4895
                }
4896
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4897
                opreg = OR_TMP0;
4898
            } else {
4899
                opreg = (modrm & 7) | REX_B(s);
4900
            }
4901

    
4902
            /* simpler op */
4903
            if (shift == 0) {
4904
                gen_shift(s, op, ot, opreg, OR_ECX);
4905
            } else {
4906
                if (shift == 2) {
4907
                    shift = ldub_code(s->pc++);
4908
                }
4909
                gen_shifti(s, op, ot, opreg, shift);
4910
            }
4911
        }
4912
        break;
4913
    case 0xd0:
4914
    case 0xd1:
4915
        /* shift Ev,1 */
4916
        shift = 1;
4917
        goto grp2;
4918
    case 0xd2:
4919
    case 0xd3:
4920
        /* shift Ev,cl */
4921
        shift = 0;
4922
        goto grp2;
4923

    
4924
    case 0x1a4: /* shld imm */
4925
        op = 0;
4926
        shift = 1;
4927
        goto do_shiftd;
4928
    case 0x1a5: /* shld cl */
4929
        op = 0;
4930
        shift = 0;
4931
        goto do_shiftd;
4932
    case 0x1ac: /* shrd imm */
4933
        op = 1;
4934
        shift = 1;
4935
        goto do_shiftd;
4936
    case 0x1ad: /* shrd cl */
4937
        op = 1;
4938
        shift = 0;
4939
    do_shiftd:
4940
        ot = dflag + OT_WORD;
4941
        modrm = ldub_code(s->pc++);
4942
        mod = (modrm >> 6) & 3;
4943
        rm = (modrm & 7) | REX_B(s);
4944
        reg = ((modrm >> 3) & 7) | rex_r;
4945
        if (mod != 3) {
4946
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4947
            opreg = OR_TMP0;
4948
        } else {
4949
            opreg = rm;
4950
        }
4951
        gen_op_mov_TN_reg(ot, 1, reg);
4952

    
4953
        if (shift) {
4954
            val = ldub_code(s->pc++);
4955
            tcg_gen_movi_tl(cpu_T3, val);
4956
        } else {
4957
            tcg_gen_ld_tl(cpu_T3, cpu_env, offsetof(CPUState, regs[R_ECX]));
4958
        }
4959
        gen_shiftd_rm_T1_T3(s, ot, opreg, op);
4960
        break;
4961

    
4962
        /************************/
4963
        /* floats */
4964
    case 0xd8 ... 0xdf:
4965
        if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
4966
            /* if CR0.EM or CR0.TS are set, generate an FPU exception */
4967
            /* XXX: what to do if illegal op ? */
4968
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);