Annotation of qemu/target-i386/translate.c, revision 1.1.1.16

1.1       root        1: /*
                      2:  *  i386 translation
1.1.1.6   root        3:  *
1.1       root        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
1.1.1.8   root       17:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1.1       root       18:  */
                     19: #include <stdarg.h>
                     20: #include <stdlib.h>
                     21: #include <stdio.h>
                     22: #include <string.h>
                     23: #include <inttypes.h>
                     24: #include <signal.h>
                     25: 
                     26: #include "cpu.h"
                     27: #include "disas.h"
1.1.1.7   root       28: #include "tcg-op.h"
1.1       root       29: 
1.1.1.7   root       30: #include "helper.h"
                     31: #define GEN_HELPER 1
                     32: #include "helper.h"
1.1       root       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
1.1.1.8   root       42: #define X86_64_DEF(...)  __VA_ARGS__
1.1       root       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
1.1.1.8   root       52: #define X86_64_DEF(...)
1.1       root       53: #define CODE64(s) 0
                     54: #define REX_X(s) 0
                     55: #define REX_B(s) 0
                     56: #endif
                     57: 
1.1.1.7   root       58: //#define MACRO_TEST   1
                     59: 
                     60: /* global register indexes */
                     61: static TCGv_ptr cpu_env;
                     62: static TCGv cpu_A0, cpu_cc_src, cpu_cc_dst, cpu_cc_tmp;
                     63: static TCGv_i32 cpu_cc_op;
1.1.1.9   root       64: static TCGv cpu_regs[CPU_NB_REGS];
1.1.1.7   root       65: /* local temps */
                     66: static TCGv cpu_T[2], cpu_T3;
                     67: /* local register indexes (only used inside old micro ops) */
                     68: static TCGv cpu_tmp0, cpu_tmp4;
                     69: static TCGv_ptr cpu_ptr0, cpu_ptr1;
                     70: static TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32;
                     71: static TCGv_i64 cpu_tmp1_i64;
1.1.1.9   root       72: static TCGv cpu_tmp5;
1.1.1.7   root       73: 
1.1.1.13  root       74: static uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
                     75: 
1.1.1.7   root       76: #include "gen-icount.h"
                     77: 
1.1       root       78: #ifdef TARGET_X86_64
                     79: static int x86_64_hregs;
                     80: #endif
                     81: 
                     82: typedef struct DisasContext {
                     83:     /* current insn context */
                     84:     int override; /* -1 if no override */
                     85:     int prefix;
                     86:     int aflag, dflag;
                     87:     target_ulong pc; /* pc = eip + cs_base */
                     88:     int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
                     89:                    static state change (stop translation) */
                     90:     /* current block context */
                     91:     target_ulong cs_base; /* base of CS segment */
                     92:     int pe;     /* protected mode */
                     93:     int code32; /* 32 bit code segment */
                     94: #ifdef TARGET_X86_64
                     95:     int lma;    /* long mode active */
                     96:     int code64; /* 64 bit code segment */
                     97:     int rex_x, rex_b;
                     98: #endif
                     99:     int ss32;   /* 32 bit stack segment */
                    100:     int cc_op;  /* current CC operation */
                    101:     int addseg; /* non zero if either DS/ES/SS have a non zero base */
                    102:     int f_st;   /* currently unused */
                    103:     int vm86;   /* vm86 mode */
                    104:     int cpl;
                    105:     int iopl;
                    106:     int tf;     /* TF cpu flag */
                    107:     int singlestep_enabled; /* "hardware" single step enabled */
                    108:     int jmp_opt; /* use direct block chaining for direct jumps */
                    109:     int mem_index; /* select memory access functions */
1.1.1.6   root      110:     uint64_t flags; /* all execution flags */
1.1       root      111:     struct TranslationBlock *tb;
                    112:     int popl_esp_hack; /* for correct popl with esp base handling */
                    113:     int rip_offset; /* only used in x86_64, but left for simplicity */
                    114:     int cpuid_features;
1.1.1.4   root      115:     int cpuid_ext_features;
1.1.1.7   root      116:     int cpuid_ext2_features;
                    117:     int cpuid_ext3_features;
1.1       root      118: } DisasContext;
                    119: 
                    120: static void gen_eob(DisasContext *s);
                    121: static void gen_jmp(DisasContext *s, target_ulong eip);
                    122: static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
                    123: 
                    124: /* i386 arith/logic operations */
                    125: enum {
1.1.1.6   root      126:     OP_ADDL,
                    127:     OP_ORL,
                    128:     OP_ADCL,
1.1       root      129:     OP_SBBL,
1.1.1.6   root      130:     OP_ANDL,
                    131:     OP_SUBL,
                    132:     OP_XORL,
1.1       root      133:     OP_CMPL,
                    134: };
                    135: 
                    136: /* i386 shift ops */
                    137: enum {
1.1.1.6   root      138:     OP_ROL,
                    139:     OP_ROR,
                    140:     OP_RCL,
                    141:     OP_RCR,
                    142:     OP_SHL,
                    143:     OP_SHR,
1.1       root      144:     OP_SHL1, /* undocumented */
                    145:     OP_SAR = 7,
                    146: };
                    147: 
                    148: enum {
1.1.1.7   root      149:     JCC_O,
                    150:     JCC_B,
                    151:     JCC_Z,
                    152:     JCC_BE,
                    153:     JCC_S,
                    154:     JCC_P,
                    155:     JCC_L,
                    156:     JCC_LE,
1.1       root      157: };
                    158: 
                    159: /* operand size */
                    160: enum {
                    161:     OT_BYTE = 0,
                    162:     OT_WORD,
1.1.1.6   root      163:     OT_LONG,
1.1       root      164:     OT_QUAD,
                    165: };
                    166: 
                    167: enum {
                    168:     /* I386 int registers */
                    169:     OR_EAX,   /* MUST be even numbered */
                    170:     OR_ECX,
                    171:     OR_EDX,
                    172:     OR_EBX,
                    173:     OR_ESP,
                    174:     OR_EBP,
                    175:     OR_ESI,
                    176:     OR_EDI,
                    177: 
                    178:     OR_TMP0 = 16,    /* temporary operand register */
                    179:     OR_TMP1,
                    180:     OR_A0, /* temporary register used when doing address evaluation */
                    181: };
                    182: 
1.1.1.7   root      183: static inline void gen_op_movl_T0_0(void)
                    184: {
                    185:     tcg_gen_movi_tl(cpu_T[0], 0);
                    186: }
                    187: 
                    188: static inline void gen_op_movl_T0_im(int32_t val)
                    189: {
                    190:     tcg_gen_movi_tl(cpu_T[0], val);
                    191: }
                    192: 
                    193: static inline void gen_op_movl_T0_imu(uint32_t val)
                    194: {
                    195:     tcg_gen_movi_tl(cpu_T[0], val);
                    196: }
                    197: 
                    198: static inline void gen_op_movl_T1_im(int32_t val)
                    199: {
                    200:     tcg_gen_movi_tl(cpu_T[1], val);
                    201: }
                    202: 
                    203: static inline void gen_op_movl_T1_imu(uint32_t val)
                    204: {
                    205:     tcg_gen_movi_tl(cpu_T[1], val);
                    206: }
                    207: 
                    208: static inline void gen_op_movl_A0_im(uint32_t val)
                    209: {
                    210:     tcg_gen_movi_tl(cpu_A0, val);
                    211: }
                    212: 
1.1       root      213: #ifdef TARGET_X86_64
1.1.1.7   root      214: static inline void gen_op_movq_A0_im(int64_t val)
                    215: {
                    216:     tcg_gen_movi_tl(cpu_A0, val);
                    217: }
                    218: #endif
1.1       root      219: 
1.1.1.7   root      220: static inline void gen_movtl_T0_im(target_ulong val)
                    221: {
                    222:     tcg_gen_movi_tl(cpu_T[0], val);
                    223: }
                    224: 
                    225: static inline void gen_movtl_T1_im(target_ulong val)
                    226: {
                    227:     tcg_gen_movi_tl(cpu_T[1], val);
                    228: }
                    229: 
                    230: static inline void gen_op_andl_T0_ffff(void)
                    231: {
                    232:     tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
                    233: }
                    234: 
                    235: static inline void gen_op_andl_T0_im(uint32_t val)
                    236: {
                    237:     tcg_gen_andi_tl(cpu_T[0], cpu_T[0], val);
                    238: }
1.1       root      239: 
1.1.1.7   root      240: static inline void gen_op_movl_T0_T1(void)
                    241: {
                    242:     tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
                    243: }
                    244: 
                    245: static inline void gen_op_andl_A0_ffff(void)
                    246: {
                    247:     tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffff);
                    248: }
                    249: 
                    250: #ifdef TARGET_X86_64
                    251: 
                    252: #define NB_OP_SIZES 4
1.1       root      253: 
                    254: #else /* !TARGET_X86_64 */
                    255: 
                    256: #define NB_OP_SIZES 3
                    257: 
                    258: #endif /* !TARGET_X86_64 */
                    259: 
1.1.1.9   root      260: #if defined(HOST_WORDS_BIGENDIAN)
1.1.1.7   root      261: #define REG_B_OFFSET (sizeof(target_ulong) - 1)
                    262: #define REG_H_OFFSET (sizeof(target_ulong) - 2)
                    263: #define REG_W_OFFSET (sizeof(target_ulong) - 2)
                    264: #define REG_L_OFFSET (sizeof(target_ulong) - 4)
                    265: #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
1.1       root      266: #else
1.1.1.7   root      267: #define REG_B_OFFSET 0
                    268: #define REG_H_OFFSET 1
                    269: #define REG_W_OFFSET 0
                    270: #define REG_L_OFFSET 0
                    271: #define REG_LH_OFFSET 4
1.1       root      272: #endif
                    273: 
1.1.1.7   root      274: static inline void gen_op_mov_reg_v(int ot, int reg, TCGv t0)
                    275: {
                    276:     switch(ot) {
                    277:     case OT_BYTE:
                    278:         if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
1.1.1.14  root      279:             tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8);
1.1.1.7   root      280:         } else {
1.1.1.14  root      281:             tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8);
1.1.1.7   root      282:         }
                    283:         break;
                    284:     case OT_WORD:
1.1.1.14  root      285:         tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16);
1.1.1.7   root      286:         break;
1.1.1.9   root      287:     default: /* XXX this shouldn't be reached;  abort? */
1.1.1.7   root      288:     case OT_LONG:
1.1.1.9   root      289:         /* For x86_64, this sets the higher half of register to zero.
                    290:            For i386, this is equivalent to a mov. */
                    291:         tcg_gen_ext32u_tl(cpu_regs[reg], t0);
1.1.1.7   root      292:         break;
1.1.1.9   root      293: #ifdef TARGET_X86_64
1.1.1.7   root      294:     case OT_QUAD:
1.1.1.9   root      295:         tcg_gen_mov_tl(cpu_regs[reg], t0);
1.1.1.7   root      296:         break;
1.1       root      297: #endif
1.1.1.7   root      298:     }
                    299: }
1.1       root      300: 
1.1.1.7   root      301: static inline void gen_op_mov_reg_T0(int ot, int reg)
                    302: {
                    303:     gen_op_mov_reg_v(ot, reg, cpu_T[0]);
                    304: }
1.1       root      305: 
1.1.1.7   root      306: static inline void gen_op_mov_reg_T1(int ot, int reg)
1.1       root      307: {
1.1.1.7   root      308:     gen_op_mov_reg_v(ot, reg, cpu_T[1]);
                    309: }
                    310: 
                    311: static inline void gen_op_mov_reg_A0(int size, int reg)
                    312: {
                    313:     switch(size) {
                    314:     case 0:
1.1.1.14  root      315:         tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_A0, 0, 16);
1.1.1.7   root      316:         break;
1.1.1.9   root      317:     default: /* XXX this shouldn't be reached;  abort? */
1.1.1.7   root      318:     case 1:
1.1.1.9   root      319:         /* For x86_64, this sets the higher half of register to zero.
                    320:            For i386, this is equivalent to a mov. */
                    321:         tcg_gen_ext32u_tl(cpu_regs[reg], cpu_A0);
1.1.1.7   root      322:         break;
1.1.1.9   root      323: #ifdef TARGET_X86_64
1.1.1.7   root      324:     case 2:
1.1.1.9   root      325:         tcg_gen_mov_tl(cpu_regs[reg], cpu_A0);
1.1.1.7   root      326:         break;
1.1       root      327: #endif
1.1.1.7   root      328:     }
                    329: }
1.1       root      330: 
1.1.1.7   root      331: static inline void gen_op_mov_v_reg(int ot, TCGv t0, int reg)
                    332: {
                    333:     switch(ot) {
                    334:     case OT_BYTE:
                    335:         if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
                    336:             goto std_case;
                    337:         } else {
1.1.1.9   root      338:             tcg_gen_shri_tl(t0, cpu_regs[reg - 4], 8);
                    339:             tcg_gen_ext8u_tl(t0, t0);
1.1.1.7   root      340:         }
                    341:         break;
                    342:     default:
                    343:     std_case:
1.1.1.9   root      344:         tcg_gen_mov_tl(t0, cpu_regs[reg]);
1.1.1.7   root      345:         break;
                    346:     }
                    347: }
1.1       root      348: 
1.1.1.7   root      349: static inline void gen_op_mov_TN_reg(int ot, int t_index, int reg)
                    350: {
                    351:     gen_op_mov_v_reg(ot, cpu_T[t_index], reg);
                    352: }
1.1       root      353: 
1.1.1.7   root      354: static inline void gen_op_movl_A0_reg(int reg)
                    355: {
1.1.1.9   root      356:     tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
1.1.1.7   root      357: }
1.1       root      358: 
1.1.1.7   root      359: static inline void gen_op_addl_A0_im(int32_t val)
                    360: {
                    361:     tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
                    362: #ifdef TARGET_X86_64
                    363:     tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
1.1       root      364: #endif
1.1.1.7   root      365: }
1.1       root      366: 
1.1.1.7   root      367: #ifdef TARGET_X86_64
                    368: static inline void gen_op_addq_A0_im(int64_t val)
                    369: {
                    370:     tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
                    371: }
1.1       root      372: #endif
1.1.1.7   root      373:     
                    374: static void gen_add_A0_im(DisasContext *s, int val)
                    375: {
                    376: #ifdef TARGET_X86_64
                    377:     if (CODE64(s))
                    378:         gen_op_addq_A0_im(val);
                    379:     else
1.1       root      380: #endif
1.1.1.7   root      381:         gen_op_addl_A0_im(val);
                    382: }
1.1       root      383: 
1.1.1.7   root      384: static inline void gen_op_addl_T0_T1(void)
                    385: {
                    386:     tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
                    387: }
1.1       root      388: 
1.1.1.7   root      389: static inline void gen_op_jmp_T0(void)
                    390: {
                    391:     tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, eip));
                    392: }
1.1       root      393: 
1.1.1.7   root      394: static inline void gen_op_add_reg_im(int size, int reg, int32_t val)
                    395: {
                    396:     switch(size) {
                    397:     case 0:
1.1.1.9   root      398:         tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
1.1.1.14  root      399:         tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0, 0, 16);
1.1.1.7   root      400:         break;
                    401:     case 1:
1.1.1.9   root      402:         tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
                    403:         /* For x86_64, this sets the higher half of register to zero.
                    404:            For i386, this is equivalent to a nop. */
                    405:         tcg_gen_ext32u_tl(cpu_tmp0, cpu_tmp0);
                    406:         tcg_gen_mov_tl(cpu_regs[reg], cpu_tmp0);
1.1.1.7   root      407:         break;
                    408: #ifdef TARGET_X86_64
                    409:     case 2:
1.1.1.9   root      410:         tcg_gen_addi_tl(cpu_regs[reg], cpu_regs[reg], val);
1.1.1.7   root      411:         break;
                    412: #endif
                    413:     }
                    414: }
1.1       root      415: 
1.1.1.7   root      416: static inline void gen_op_add_reg_T0(int size, int reg)
                    417: {
                    418:     switch(size) {
                    419:     case 0:
1.1.1.9   root      420:         tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]);
1.1.1.14  root      421:         tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0, 0, 16);
1.1.1.7   root      422:         break;
                    423:     case 1:
1.1.1.9   root      424:         tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]);
                    425:         /* For x86_64, this sets the higher half of register to zero.
                    426:            For i386, this is equivalent to a nop. */
                    427:         tcg_gen_ext32u_tl(cpu_tmp0, cpu_tmp0);
                    428:         tcg_gen_mov_tl(cpu_regs[reg], cpu_tmp0);
1.1.1.7   root      429:         break;
                    430: #ifdef TARGET_X86_64
                    431:     case 2:
1.1.1.9   root      432:         tcg_gen_add_tl(cpu_regs[reg], cpu_regs[reg], cpu_T[0]);
1.1.1.7   root      433:         break;
                    434: #endif
                    435:     }
                    436: }
1.1       root      437: 
1.1.1.7   root      438: static inline void gen_op_set_cc_op(int32_t val)
                    439: {
                    440:     tcg_gen_movi_i32(cpu_cc_op, val);
                    441: }
1.1       root      442: 
1.1.1.7   root      443: static inline void gen_op_addl_A0_reg_sN(int shift, int reg)
                    444: {
1.1.1.9   root      445:     tcg_gen_mov_tl(cpu_tmp0, cpu_regs[reg]);
                    446:     if (shift != 0)
1.1.1.7   root      447:         tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
                    448:     tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
1.1.1.9   root      449:     /* For x86_64, this sets the higher half of register to zero.
                    450:        For i386, this is equivalent to a nop. */
                    451:     tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
1.1.1.7   root      452: }
1.1       root      453: 
1.1.1.7   root      454: static inline void gen_op_movl_A0_seg(int reg)
                    455: {
                    456:     tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUState, segs[reg].base) + REG_L_OFFSET);
                    457: }
1.1       root      458: 
1.1.1.7   root      459: static inline void gen_op_addl_A0_seg(int reg)
                    460: {
                    461:     tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, segs[reg].base));
                    462:     tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
                    463: #ifdef TARGET_X86_64
                    464:     tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
                    465: #endif
                    466: }
1.1       root      467: 
1.1.1.7   root      468: #ifdef TARGET_X86_64
                    469: static inline void gen_op_movq_A0_seg(int reg)
                    470: {
                    471:     tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUState, segs[reg].base));
                    472: }
1.1       root      473: 
1.1.1.7   root      474: static inline void gen_op_addq_A0_seg(int reg)
                    475: {
                    476:     tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, segs[reg].base));
                    477:     tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
                    478: }
1.1       root      479: 
1.1.1.7   root      480: static inline void gen_op_movq_A0_reg(int reg)
                    481: {
1.1.1.9   root      482:     tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
1.1.1.7   root      483: }
1.1       root      484: 
1.1.1.7   root      485: static inline void gen_op_addq_A0_reg_sN(int shift, int reg)
                    486: {
1.1.1.9   root      487:     tcg_gen_mov_tl(cpu_tmp0, cpu_regs[reg]);
                    488:     if (shift != 0)
1.1.1.7   root      489:         tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
                    490:     tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
                    491: }
1.1       root      492: #endif
                    493: 
1.1.1.7   root      494: static inline void gen_op_lds_T0_A0(int idx)
                    495: {
                    496:     int mem_index = (idx >> 2) - 1;
                    497:     switch(idx & 3) {
                    498:     case 0:
                    499:         tcg_gen_qemu_ld8s(cpu_T[0], cpu_A0, mem_index);
                    500:         break;
                    501:     case 1:
                    502:         tcg_gen_qemu_ld16s(cpu_T[0], cpu_A0, mem_index);
                    503:         break;
                    504:     default:
                    505:     case 2:
                    506:         tcg_gen_qemu_ld32s(cpu_T[0], cpu_A0, mem_index);
                    507:         break;
                    508:     }
                    509: }
1.1       root      510: 
1.1.1.7   root      511: static inline void gen_op_ld_v(int idx, TCGv t0, TCGv a0)
                    512: {
                    513:     int mem_index = (idx >> 2) - 1;
                    514:     switch(idx & 3) {
                    515:     case 0:
                    516:         tcg_gen_qemu_ld8u(t0, a0, mem_index);
                    517:         break;
                    518:     case 1:
                    519:         tcg_gen_qemu_ld16u(t0, a0, mem_index);
                    520:         break;
                    521:     case 2:
                    522:         tcg_gen_qemu_ld32u(t0, a0, mem_index);
                    523:         break;
                    524:     default:
                    525:     case 3:
                    526:         /* Should never happen on 32-bit targets.  */
                    527: #ifdef TARGET_X86_64
                    528:         tcg_gen_qemu_ld64(t0, a0, mem_index);
1.1       root      529: #endif
1.1.1.7   root      530:         break;
                    531:     }
                    532: }
1.1       root      533: 
1.1.1.7   root      534: /* XXX: always use ldu or lds */
                    535: static inline void gen_op_ld_T0_A0(int idx)
                    536: {
                    537:     gen_op_ld_v(idx, cpu_T[0], cpu_A0);
                    538: }
1.1       root      539: 
1.1.1.7   root      540: static inline void gen_op_ldu_T0_A0(int idx)
                    541: {
                    542:     gen_op_ld_v(idx, cpu_T[0], cpu_A0);
                    543: }
1.1       root      544: 
1.1.1.7   root      545: static inline void gen_op_ld_T1_A0(int idx)
                    546: {
                    547:     gen_op_ld_v(idx, cpu_T[1], cpu_A0);
                    548: }
1.1       root      549: 
1.1.1.7   root      550: static inline void gen_op_st_v(int idx, TCGv t0, TCGv a0)
                    551: {
                    552:     int mem_index = (idx >> 2) - 1;
                    553:     switch(idx & 3) {
                    554:     case 0:
                    555:         tcg_gen_qemu_st8(t0, a0, mem_index);
                    556:         break;
                    557:     case 1:
                    558:         tcg_gen_qemu_st16(t0, a0, mem_index);
                    559:         break;
                    560:     case 2:
                    561:         tcg_gen_qemu_st32(t0, a0, mem_index);
                    562:         break;
                    563:     default:
                    564:     case 3:
                    565:         /* Should never happen on 32-bit targets.  */
                    566: #ifdef TARGET_X86_64
                    567:         tcg_gen_qemu_st64(t0, a0, mem_index);
1.1       root      568: #endif
1.1.1.7   root      569:         break;
                    570:     }
                    571: }
1.1       root      572: 
1.1.1.7   root      573: static inline void gen_op_st_T0_A0(int idx)
                    574: {
                    575:     gen_op_st_v(idx, cpu_T[0], cpu_A0);
                    576: }
1.1       root      577: 
1.1.1.7   root      578: static inline void gen_op_st_T1_A0(int idx)
                    579: {
                    580:     gen_op_st_v(idx, cpu_T[1], cpu_A0);
                    581: }
1.1       root      582: 
                    583: static inline void gen_jmp_im(target_ulong pc)
                    584: {
1.1.1.7   root      585:     tcg_gen_movi_tl(cpu_tmp0, pc);
                    586:     tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, eip));
1.1       root      587: }
                    588: 
                    589: static inline void gen_string_movl_A0_ESI(DisasContext *s)
                    590: {
                    591:     int override;
                    592: 
                    593:     override = s->override;
                    594: #ifdef TARGET_X86_64
                    595:     if (s->aflag == 2) {
                    596:         if (override >= 0) {
1.1.1.7   root      597:             gen_op_movq_A0_seg(override);
                    598:             gen_op_addq_A0_reg_sN(0, R_ESI);
1.1       root      599:         } else {
1.1.1.7   root      600:             gen_op_movq_A0_reg(R_ESI);
1.1       root      601:         }
                    602:     } else
                    603: #endif
                    604:     if (s->aflag) {
                    605:         /* 32 bit address */
                    606:         if (s->addseg && override < 0)
                    607:             override = R_DS;
                    608:         if (override >= 0) {
1.1.1.7   root      609:             gen_op_movl_A0_seg(override);
                    610:             gen_op_addl_A0_reg_sN(0, R_ESI);
1.1       root      611:         } else {
1.1.1.7   root      612:             gen_op_movl_A0_reg(R_ESI);
1.1       root      613:         }
                    614:     } else {
                    615:         /* 16 address, always override */
                    616:         if (override < 0)
                    617:             override = R_DS;
1.1.1.7   root      618:         gen_op_movl_A0_reg(R_ESI);
1.1       root      619:         gen_op_andl_A0_ffff();
1.1.1.7   root      620:         gen_op_addl_A0_seg(override);
1.1       root      621:     }
                    622: }
                    623: 
                    624: static inline void gen_string_movl_A0_EDI(DisasContext *s)
                    625: {
                    626: #ifdef TARGET_X86_64
                    627:     if (s->aflag == 2) {
1.1.1.7   root      628:         gen_op_movq_A0_reg(R_EDI);
1.1       root      629:     } else
                    630: #endif
                    631:     if (s->aflag) {
                    632:         if (s->addseg) {
1.1.1.7   root      633:             gen_op_movl_A0_seg(R_ES);
                    634:             gen_op_addl_A0_reg_sN(0, R_EDI);
1.1       root      635:         } else {
1.1.1.7   root      636:             gen_op_movl_A0_reg(R_EDI);
1.1       root      637:         }
                    638:     } else {
1.1.1.7   root      639:         gen_op_movl_A0_reg(R_EDI);
1.1       root      640:         gen_op_andl_A0_ffff();
1.1.1.7   root      641:         gen_op_addl_A0_seg(R_ES);
1.1       root      642:     }
                    643: }
                    644: 
1.1.1.7   root      645: static inline void gen_op_movl_T0_Dshift(int ot) 
                    646: {
                    647:     tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUState, df));
                    648:     tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot);
1.1       root      649: };
                    650: 
1.1.1.7   root      651: static void gen_extu(int ot, TCGv reg)
                    652: {
                    653:     switch(ot) {
                    654:     case OT_BYTE:
                    655:         tcg_gen_ext8u_tl(reg, reg);
                    656:         break;
                    657:     case OT_WORD:
                    658:         tcg_gen_ext16u_tl(reg, reg);
                    659:         break;
                    660:     case OT_LONG:
                    661:         tcg_gen_ext32u_tl(reg, reg);
                    662:         break;
                    663:     default:
                    664:         break;
                    665:     }
                    666: }
1.1       root      667: 
1.1.1.7   root      668: static void gen_exts(int ot, TCGv reg)
                    669: {
                    670:     switch(ot) {
                    671:     case OT_BYTE:
                    672:         tcg_gen_ext8s_tl(reg, reg);
                    673:         break;
                    674:     case OT_WORD:
                    675:         tcg_gen_ext16s_tl(reg, reg);
                    676:         break;
                    677:     case OT_LONG:
                    678:         tcg_gen_ext32s_tl(reg, reg);
                    679:         break;
                    680:     default:
                    681:         break;
                    682:     }
                    683: }
1.1       root      684: 
1.1.1.7   root      685: static inline void gen_op_jnz_ecx(int size, int label1)
                    686: {
1.1.1.9   root      687:     tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
1.1.1.7   root      688:     gen_extu(size + 1, cpu_tmp0);
                    689:     tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
                    690: }
1.1       root      691: 
1.1.1.7   root      692: static inline void gen_op_jz_ecx(int size, int label1)
                    693: {
1.1.1.9   root      694:     tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
1.1.1.7   root      695:     gen_extu(size + 1, cpu_tmp0);
                    696:     tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
                    697: }
1.1       root      698: 
1.1.1.7   root      699: static void gen_helper_in_func(int ot, TCGv v, TCGv_i32 n)
                    700: {
                    701:     switch (ot) {
                    702:     case 0: gen_helper_inb(v, n); break;
                    703:     case 1: gen_helper_inw(v, n); break;
                    704:     case 2: gen_helper_inl(v, n); break;
                    705:     }
1.1       root      706: 
1.1.1.7   root      707: }
1.1       root      708: 
1.1.1.7   root      709: static void gen_helper_out_func(int ot, TCGv_i32 v, TCGv_i32 n)
                    710: {
                    711:     switch (ot) {
                    712:     case 0: gen_helper_outb(v, n); break;
                    713:     case 1: gen_helper_outw(v, n); break;
                    714:     case 2: gen_helper_outl(v, n); break;
                    715:     }
1.1       root      716: 
1.1.1.7   root      717: }
1.1       root      718: 
1.1.1.7   root      719: static void gen_check_io(DisasContext *s, int ot, target_ulong cur_eip,
                    720:                          uint32_t svm_flags)
1.1       root      721: {
1.1.1.7   root      722:     int state_saved;
                    723:     target_ulong next_eip;
                    724: 
                    725:     state_saved = 0;
1.1       root      726:     if (s->pe && (s->cpl > s->iopl || s->vm86)) {
                    727:         if (s->cc_op != CC_OP_DYNAMIC)
                    728:             gen_op_set_cc_op(s->cc_op);
                    729:         gen_jmp_im(cur_eip);
1.1.1.7   root      730:         state_saved = 1;
                    731:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                    732:         switch (ot) {
                    733:         case 0: gen_helper_check_iob(cpu_tmp2_i32); break;
                    734:         case 1: gen_helper_check_iow(cpu_tmp2_i32); break;
                    735:         case 2: gen_helper_check_iol(cpu_tmp2_i32); break;
                    736:         }
                    737:     }
                    738:     if(s->flags & HF_SVMI_MASK) {
                    739:         if (!state_saved) {
                    740:             if (s->cc_op != CC_OP_DYNAMIC)
                    741:                 gen_op_set_cc_op(s->cc_op);
                    742:             gen_jmp_im(cur_eip);
                    743:         }
                    744:         svm_flags |= (1 << (4 + ot));
                    745:         next_eip = s->pc - s->cs_base;
                    746:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                    747:         gen_helper_svm_check_io(cpu_tmp2_i32, tcg_const_i32(svm_flags),
                    748:                                 tcg_const_i32(next_eip - cur_eip));
1.1       root      749:     }
                    750: }
                    751: 
                    752: static inline void gen_movs(DisasContext *s, int ot)
                    753: {
                    754:     gen_string_movl_A0_ESI(s);
1.1.1.7   root      755:     gen_op_ld_T0_A0(ot + s->mem_index);
1.1       root      756:     gen_string_movl_A0_EDI(s);
1.1.1.7   root      757:     gen_op_st_T0_A0(ot + s->mem_index);
                    758:     gen_op_movl_T0_Dshift(ot);
                    759:     gen_op_add_reg_T0(s->aflag, R_ESI);
                    760:     gen_op_add_reg_T0(s->aflag, R_EDI);
1.1       root      761: }
                    762: 
                    763: static inline void gen_update_cc_op(DisasContext *s)
                    764: {
                    765:     if (s->cc_op != CC_OP_DYNAMIC) {
                    766:         gen_op_set_cc_op(s->cc_op);
                    767:         s->cc_op = CC_OP_DYNAMIC;
                    768:     }
                    769: }
                    770: 
1.1.1.7   root      771: static void gen_op_update1_cc(void)
                    772: {
                    773:     tcg_gen_discard_tl(cpu_cc_src);
                    774:     tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
                    775: }
                    776: 
                    777: static void gen_op_update2_cc(void)
                    778: {
                    779:     tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
                    780:     tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
                    781: }
                    782: 
                    783: static inline void gen_op_cmpl_T0_T1_cc(void)
                    784: {
                    785:     tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
                    786:     tcg_gen_sub_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
                    787: }
                    788: 
                    789: static inline void gen_op_testl_T0_T1_cc(void)
                    790: {
                    791:     tcg_gen_discard_tl(cpu_cc_src);
                    792:     tcg_gen_and_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
                    793: }
                    794: 
                    795: static void gen_op_update_neg_cc(void)
                    796: {
                    797:     tcg_gen_neg_tl(cpu_cc_src, cpu_T[0]);
                    798:     tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
                    799: }
                    800: 
                    801: /* compute eflags.C to reg */
                    802: static void gen_compute_eflags_c(TCGv reg)
                    803: {
                    804:     gen_helper_cc_compute_c(cpu_tmp2_i32, cpu_cc_op);
                    805:     tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);
                    806: }
                    807: 
                    808: /* compute all eflags to cc_src */
                    809: static void gen_compute_eflags(TCGv reg)
                    810: {
                    811:     gen_helper_cc_compute_all(cpu_tmp2_i32, cpu_cc_op);
                    812:     tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);
                    813: }
                    814: 
                    815: static inline void gen_setcc_slow_T0(DisasContext *s, int jcc_op)
                    816: {
                    817:     if (s->cc_op != CC_OP_DYNAMIC)
                    818:         gen_op_set_cc_op(s->cc_op);
                    819:     switch(jcc_op) {
                    820:     case JCC_O:
                    821:         gen_compute_eflags(cpu_T[0]);
                    822:         tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 11);
                    823:         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
                    824:         break;
                    825:     case JCC_B:
                    826:         gen_compute_eflags_c(cpu_T[0]);
                    827:         break;
                    828:     case JCC_Z:
                    829:         gen_compute_eflags(cpu_T[0]);
                    830:         tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 6);
                    831:         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
                    832:         break;
                    833:     case JCC_BE:
                    834:         gen_compute_eflags(cpu_tmp0);
                    835:         tcg_gen_shri_tl(cpu_T[0], cpu_tmp0, 6);
                    836:         tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
                    837:         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
                    838:         break;
                    839:     case JCC_S:
                    840:         gen_compute_eflags(cpu_T[0]);
                    841:         tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 7);
                    842:         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
                    843:         break;
                    844:     case JCC_P:
                    845:         gen_compute_eflags(cpu_T[0]);
                    846:         tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 2);
                    847:         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
                    848:         break;
                    849:     case JCC_L:
                    850:         gen_compute_eflags(cpu_tmp0);
                    851:         tcg_gen_shri_tl(cpu_T[0], cpu_tmp0, 11); /* CC_O */
                    852:         tcg_gen_shri_tl(cpu_tmp0, cpu_tmp0, 7); /* CC_S */
                    853:         tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
                    854:         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
                    855:         break;
                    856:     default:
                    857:     case JCC_LE:
                    858:         gen_compute_eflags(cpu_tmp0);
                    859:         tcg_gen_shri_tl(cpu_T[0], cpu_tmp0, 11); /* CC_O */
                    860:         tcg_gen_shri_tl(cpu_tmp4, cpu_tmp0, 7); /* CC_S */
                    861:         tcg_gen_shri_tl(cpu_tmp0, cpu_tmp0, 6); /* CC_Z */
                    862:         tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
                    863:         tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
                    864:         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
                    865:         break;
                    866:     }
                    867: }
                    868: 
                    869: /* return true if setcc_slow is not needed (WARNING: must be kept in
                    870:    sync with gen_jcc1) */
                    871: static int is_fast_jcc_case(DisasContext *s, int b)
                    872: {
                    873:     int jcc_op;
                    874:     jcc_op = (b >> 1) & 7;
                    875:     switch(s->cc_op) {
                    876:         /* we optimize the cmp/jcc case */
                    877:     case CC_OP_SUBB:
                    878:     case CC_OP_SUBW:
                    879:     case CC_OP_SUBL:
                    880:     case CC_OP_SUBQ:
                    881:         if (jcc_op == JCC_O || jcc_op == JCC_P)
                    882:             goto slow_jcc;
                    883:         break;
                    884: 
                    885:         /* some jumps are easy to compute */
                    886:     case CC_OP_ADDB:
                    887:     case CC_OP_ADDW:
                    888:     case CC_OP_ADDL:
                    889:     case CC_OP_ADDQ:
                    890: 
                    891:     case CC_OP_LOGICB:
                    892:     case CC_OP_LOGICW:
                    893:     case CC_OP_LOGICL:
                    894:     case CC_OP_LOGICQ:
                    895: 
                    896:     case CC_OP_INCB:
                    897:     case CC_OP_INCW:
                    898:     case CC_OP_INCL:
                    899:     case CC_OP_INCQ:
                    900: 
                    901:     case CC_OP_DECB:
                    902:     case CC_OP_DECW:
                    903:     case CC_OP_DECL:
                    904:     case CC_OP_DECQ:
                    905: 
                    906:     case CC_OP_SHLB:
                    907:     case CC_OP_SHLW:
                    908:     case CC_OP_SHLL:
                    909:     case CC_OP_SHLQ:
                    910:         if (jcc_op != JCC_Z && jcc_op != JCC_S)
                    911:             goto slow_jcc;
                    912:         break;
                    913:     default:
                    914:     slow_jcc:
                    915:         return 0;
                    916:     }
                    917:     return 1;
                    918: }
                    919: 
                    920: /* generate a conditional jump to label 'l1' according to jump opcode
                    921:    value 'b'. In the fast case, T0 is guaranted not to be used. */
                    922: static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1)
                    923: {
                    924:     int inv, jcc_op, size, cond;
                    925:     TCGv t0;
                    926: 
                    927:     inv = b & 1;
                    928:     jcc_op = (b >> 1) & 7;
                    929: 
                    930:     switch(cc_op) {
                    931:         /* we optimize the cmp/jcc case */
                    932:     case CC_OP_SUBB:
                    933:     case CC_OP_SUBW:
                    934:     case CC_OP_SUBL:
                    935:     case CC_OP_SUBQ:
                    936:         
                    937:         size = cc_op - CC_OP_SUBB;
                    938:         switch(jcc_op) {
                    939:         case JCC_Z:
                    940:         fast_jcc_z:
                    941:             switch(size) {
                    942:             case 0:
                    943:                 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xff);
                    944:                 t0 = cpu_tmp0;
                    945:                 break;
                    946:             case 1:
                    947:                 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xffff);
                    948:                 t0 = cpu_tmp0;
                    949:                 break;
                    950: #ifdef TARGET_X86_64
                    951:             case 2:
                    952:                 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xffffffff);
                    953:                 t0 = cpu_tmp0;
                    954:                 break;
                    955: #endif
                    956:             default:
                    957:                 t0 = cpu_cc_dst;
                    958:                 break;
                    959:             }
                    960:             tcg_gen_brcondi_tl(inv ? TCG_COND_NE : TCG_COND_EQ, t0, 0, l1);
                    961:             break;
                    962:         case JCC_S:
                    963:         fast_jcc_s:
                    964:             switch(size) {
                    965:             case 0:
                    966:                 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x80);
                    967:                 tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, 
                    968:                                    0, l1);
                    969:                 break;
                    970:             case 1:
                    971:                 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x8000);
                    972:                 tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, 
                    973:                                    0, l1);
                    974:                 break;
                    975: #ifdef TARGET_X86_64
                    976:             case 2:
                    977:                 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x80000000);
                    978:                 tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, 
                    979:                                    0, l1);
                    980:                 break;
                    981: #endif
                    982:             default:
                    983:                 tcg_gen_brcondi_tl(inv ? TCG_COND_GE : TCG_COND_LT, cpu_cc_dst, 
                    984:                                    0, l1);
                    985:                 break;
                    986:             }
                    987:             break;
                    988:             
                    989:         case JCC_B:
                    990:             cond = inv ? TCG_COND_GEU : TCG_COND_LTU;
                    991:             goto fast_jcc_b;
                    992:         case JCC_BE:
                    993:             cond = inv ? TCG_COND_GTU : TCG_COND_LEU;
                    994:         fast_jcc_b:
                    995:             tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);
                    996:             switch(size) {
                    997:             case 0:
                    998:                 t0 = cpu_tmp0;
                    999:                 tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xff);
                   1000:                 tcg_gen_andi_tl(t0, cpu_cc_src, 0xff);
                   1001:                 break;
                   1002:             case 1:
                   1003:                 t0 = cpu_tmp0;
                   1004:                 tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xffff);
                   1005:                 tcg_gen_andi_tl(t0, cpu_cc_src, 0xffff);
                   1006:                 break;
                   1007: #ifdef TARGET_X86_64
                   1008:             case 2:
                   1009:                 t0 = cpu_tmp0;
                   1010:                 tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xffffffff);
                   1011:                 tcg_gen_andi_tl(t0, cpu_cc_src, 0xffffffff);
                   1012:                 break;
                   1013: #endif
                   1014:             default:
                   1015:                 t0 = cpu_cc_src;
                   1016:                 break;
                   1017:             }
                   1018:             tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1);
                   1019:             break;
                   1020:             
                   1021:         case JCC_L:
                   1022:             cond = inv ? TCG_COND_GE : TCG_COND_LT;
                   1023:             goto fast_jcc_l;
                   1024:         case JCC_LE:
                   1025:             cond = inv ? TCG_COND_GT : TCG_COND_LE;
                   1026:         fast_jcc_l:
                   1027:             tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);
                   1028:             switch(size) {
                   1029:             case 0:
                   1030:                 t0 = cpu_tmp0;
                   1031:                 tcg_gen_ext8s_tl(cpu_tmp4, cpu_tmp4);
                   1032:                 tcg_gen_ext8s_tl(t0, cpu_cc_src);
                   1033:                 break;
                   1034:             case 1:
                   1035:                 t0 = cpu_tmp0;
                   1036:                 tcg_gen_ext16s_tl(cpu_tmp4, cpu_tmp4);
                   1037:                 tcg_gen_ext16s_tl(t0, cpu_cc_src);
                   1038:                 break;
                   1039: #ifdef TARGET_X86_64
                   1040:             case 2:
                   1041:                 t0 = cpu_tmp0;
                   1042:                 tcg_gen_ext32s_tl(cpu_tmp4, cpu_tmp4);
                   1043:                 tcg_gen_ext32s_tl(t0, cpu_cc_src);
                   1044:                 break;
                   1045: #endif
                   1046:             default:
                   1047:                 t0 = cpu_cc_src;
                   1048:                 break;
                   1049:             }
                   1050:             tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1);
                   1051:             break;
                   1052:             
                   1053:         default:
                   1054:             goto slow_jcc;
                   1055:         }
                   1056:         break;
                   1057:         
                   1058:         /* some jumps are easy to compute */
                   1059:     case CC_OP_ADDB:
                   1060:     case CC_OP_ADDW:
                   1061:     case CC_OP_ADDL:
                   1062:     case CC_OP_ADDQ:
                   1063:         
                   1064:     case CC_OP_ADCB:
                   1065:     case CC_OP_ADCW:
                   1066:     case CC_OP_ADCL:
                   1067:     case CC_OP_ADCQ:
                   1068:         
                   1069:     case CC_OP_SBBB:
                   1070:     case CC_OP_SBBW:
                   1071:     case CC_OP_SBBL:
                   1072:     case CC_OP_SBBQ:
                   1073:         
                   1074:     case CC_OP_LOGICB:
                   1075:     case CC_OP_LOGICW:
                   1076:     case CC_OP_LOGICL:
                   1077:     case CC_OP_LOGICQ:
                   1078:         
                   1079:     case CC_OP_INCB:
                   1080:     case CC_OP_INCW:
                   1081:     case CC_OP_INCL:
                   1082:     case CC_OP_INCQ:
                   1083:         
                   1084:     case CC_OP_DECB:
                   1085:     case CC_OP_DECW:
                   1086:     case CC_OP_DECL:
                   1087:     case CC_OP_DECQ:
                   1088:         
                   1089:     case CC_OP_SHLB:
                   1090:     case CC_OP_SHLW:
                   1091:     case CC_OP_SHLL:
                   1092:     case CC_OP_SHLQ:
                   1093:         
                   1094:     case CC_OP_SARB:
                   1095:     case CC_OP_SARW:
                   1096:     case CC_OP_SARL:
                   1097:     case CC_OP_SARQ:
                   1098:         switch(jcc_op) {
                   1099:         case JCC_Z:
                   1100:             size = (cc_op - CC_OP_ADDB) & 3;
                   1101:             goto fast_jcc_z;
                   1102:         case JCC_S:
                   1103:             size = (cc_op - CC_OP_ADDB) & 3;
                   1104:             goto fast_jcc_s;
                   1105:         default:
                   1106:             goto slow_jcc;
                   1107:         }
                   1108:         break;
                   1109:     default:
                   1110:     slow_jcc:
                   1111:         gen_setcc_slow_T0(s, jcc_op);
                   1112:         tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, 
                   1113:                            cpu_T[0], 0, l1);
                   1114:         break;
                   1115:     }
                   1116: }
                   1117: 
1.1       root     1118: /* XXX: does not work with gdbstub "ice" single step - not a
                   1119:    serious problem */
                   1120: static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
                   1121: {
                   1122:     int l1, l2;
                   1123: 
                   1124:     l1 = gen_new_label();
                   1125:     l2 = gen_new_label();
1.1.1.7   root     1126:     gen_op_jnz_ecx(s->aflag, l1);
1.1       root     1127:     gen_set_label(l2);
                   1128:     gen_jmp_tb(s, next_eip, 1);
                   1129:     gen_set_label(l1);
                   1130:     return l2;
                   1131: }
                   1132: 
                   1133: static inline void gen_stos(DisasContext *s, int ot)
                   1134: {
1.1.1.7   root     1135:     gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
1.1       root     1136:     gen_string_movl_A0_EDI(s);
1.1.1.7   root     1137:     gen_op_st_T0_A0(ot + s->mem_index);
                   1138:     gen_op_movl_T0_Dshift(ot);
                   1139:     gen_op_add_reg_T0(s->aflag, R_EDI);
1.1       root     1140: }
                   1141: 
                   1142: static inline void gen_lods(DisasContext *s, int ot)
                   1143: {
                   1144:     gen_string_movl_A0_ESI(s);
1.1.1.7   root     1145:     gen_op_ld_T0_A0(ot + s->mem_index);
                   1146:     gen_op_mov_reg_T0(ot, R_EAX);
                   1147:     gen_op_movl_T0_Dshift(ot);
                   1148:     gen_op_add_reg_T0(s->aflag, R_ESI);
1.1       root     1149: }
                   1150: 
                   1151: static inline void gen_scas(DisasContext *s, int ot)
                   1152: {
1.1.1.7   root     1153:     gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
1.1       root     1154:     gen_string_movl_A0_EDI(s);
1.1.1.7   root     1155:     gen_op_ld_T1_A0(ot + s->mem_index);
1.1       root     1156:     gen_op_cmpl_T0_T1_cc();
1.1.1.7   root     1157:     gen_op_movl_T0_Dshift(ot);
                   1158:     gen_op_add_reg_T0(s->aflag, R_EDI);
1.1       root     1159: }
                   1160: 
                   1161: static inline void gen_cmps(DisasContext *s, int ot)
                   1162: {
                   1163:     gen_string_movl_A0_ESI(s);
1.1.1.7   root     1164:     gen_op_ld_T0_A0(ot + s->mem_index);
1.1       root     1165:     gen_string_movl_A0_EDI(s);
1.1.1.7   root     1166:     gen_op_ld_T1_A0(ot + s->mem_index);
1.1       root     1167:     gen_op_cmpl_T0_T1_cc();
1.1.1.7   root     1168:     gen_op_movl_T0_Dshift(ot);
                   1169:     gen_op_add_reg_T0(s->aflag, R_ESI);
                   1170:     gen_op_add_reg_T0(s->aflag, R_EDI);
1.1       root     1171: }
                   1172: 
                   1173: static inline void gen_ins(DisasContext *s, int ot)
                   1174: {
1.1.1.7   root     1175:     if (use_icount)
                   1176:         gen_io_start();
1.1       root     1177:     gen_string_movl_A0_EDI(s);
1.1.1.7   root     1178:     /* Note: we must do this dummy write first to be restartable in
                   1179:        case of page fault. */
1.1       root     1180:     gen_op_movl_T0_0();
1.1.1.7   root     1181:     gen_op_st_T0_A0(ot + s->mem_index);
                   1182:     gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
                   1183:     tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
                   1184:     tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
                   1185:     gen_helper_in_func(ot, cpu_T[0], cpu_tmp2_i32);
                   1186:     gen_op_st_T0_A0(ot + s->mem_index);
                   1187:     gen_op_movl_T0_Dshift(ot);
                   1188:     gen_op_add_reg_T0(s->aflag, R_EDI);
                   1189:     if (use_icount)
                   1190:         gen_io_end();
1.1       root     1191: }
                   1192: 
                   1193: static inline void gen_outs(DisasContext *s, int ot)
                   1194: {
1.1.1.7   root     1195:     if (use_icount)
                   1196:         gen_io_start();
1.1       root     1197:     gen_string_movl_A0_ESI(s);
1.1.1.7   root     1198:     gen_op_ld_T0_A0(ot + s->mem_index);
                   1199: 
                   1200:     gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
                   1201:     tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
                   1202:     tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
                   1203:     tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]);
                   1204:     gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
                   1205: 
                   1206:     gen_op_movl_T0_Dshift(ot);
                   1207:     gen_op_add_reg_T0(s->aflag, R_ESI);
                   1208:     if (use_icount)
                   1209:         gen_io_end();
1.1       root     1210: }
                   1211: 
                   1212: /* same method as Valgrind : we generate jumps to current or next
                   1213:    instruction */
                   1214: #define GEN_REPZ(op)                                                          \
                   1215: static inline void gen_repz_ ## op(DisasContext *s, int ot,                   \
                   1216:                                  target_ulong cur_eip, target_ulong next_eip) \
                   1217: {                                                                             \
                   1218:     int l2;\
                   1219:     gen_update_cc_op(s);                                                      \
                   1220:     l2 = gen_jz_ecx_string(s, next_eip);                                      \
                   1221:     gen_ ## op(s, ot);                                                        \
1.1.1.7   root     1222:     gen_op_add_reg_im(s->aflag, R_ECX, -1);                                   \
1.1       root     1223:     /* a loop would cause two single step exceptions if ECX = 1               \
                   1224:        before rep string_insn */                                              \
                   1225:     if (!s->jmp_opt)                                                          \
1.1.1.7   root     1226:         gen_op_jz_ecx(s->aflag, l2);                                          \
1.1       root     1227:     gen_jmp(s, cur_eip);                                                      \
                   1228: }
                   1229: 
                   1230: #define GEN_REPZ2(op)                                                         \
                   1231: static inline void gen_repz_ ## op(DisasContext *s, int ot,                   \
                   1232:                                    target_ulong cur_eip,                      \
                   1233:                                    target_ulong next_eip,                     \
                   1234:                                    int nz)                                    \
                   1235: {                                                                             \
                   1236:     int l2;\
                   1237:     gen_update_cc_op(s);                                                      \
                   1238:     l2 = gen_jz_ecx_string(s, next_eip);                                      \
                   1239:     gen_ ## op(s, ot);                                                        \
1.1.1.7   root     1240:     gen_op_add_reg_im(s->aflag, R_ECX, -1);                                   \
1.1       root     1241:     gen_op_set_cc_op(CC_OP_SUBB + ot);                                        \
1.1.1.7   root     1242:     gen_jcc1(s, CC_OP_SUBB + ot, (JCC_Z << 1) | (nz ^ 1), l2);                \
1.1       root     1243:     if (!s->jmp_opt)                                                          \
1.1.1.7   root     1244:         gen_op_jz_ecx(s->aflag, l2);                                          \
1.1       root     1245:     gen_jmp(s, cur_eip);                                                      \
                   1246: }
                   1247: 
                   1248: GEN_REPZ(movs)
                   1249: GEN_REPZ(stos)
                   1250: GEN_REPZ(lods)
                   1251: GEN_REPZ(ins)
                   1252: GEN_REPZ(outs)
                   1253: GEN_REPZ2(scas)
                   1254: GEN_REPZ2(cmps)
                   1255: 
1.1.1.7   root     1256: static void gen_helper_fp_arith_ST0_FT0(int op)
                   1257: {
                   1258:     switch (op) {
                   1259:     case 0: gen_helper_fadd_ST0_FT0(); break;
                   1260:     case 1: gen_helper_fmul_ST0_FT0(); break;
                   1261:     case 2: gen_helper_fcom_ST0_FT0(); break;
                   1262:     case 3: gen_helper_fcom_ST0_FT0(); break;
                   1263:     case 4: gen_helper_fsub_ST0_FT0(); break;
                   1264:     case 5: gen_helper_fsubr_ST0_FT0(); break;
                   1265:     case 6: gen_helper_fdiv_ST0_FT0(); break;
                   1266:     case 7: gen_helper_fdivr_ST0_FT0(); break;
                   1267:     }
                   1268: }
1.1       root     1269: 
                   1270: /* NOTE the exception in "r" op ordering */
1.1.1.7   root     1271: static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
                   1272: {
                   1273:     TCGv_i32 tmp = tcg_const_i32(opreg);
                   1274:     switch (op) {
                   1275:     case 0: gen_helper_fadd_STN_ST0(tmp); break;
                   1276:     case 1: gen_helper_fmul_STN_ST0(tmp); break;
                   1277:     case 4: gen_helper_fsubr_STN_ST0(tmp); break;
                   1278:     case 5: gen_helper_fsub_STN_ST0(tmp); break;
                   1279:     case 6: gen_helper_fdivr_STN_ST0(tmp); break;
                   1280:     case 7: gen_helper_fdiv_STN_ST0(tmp); break;
                   1281:     }
                   1282: }
1.1       root     1283: 
                   1284: /* if d == OR_TMP0, it means memory operand (address in A0) */
                   1285: static void gen_op(DisasContext *s1, int op, int ot, int d)
                   1286: {
                   1287:     if (d != OR_TMP0) {
1.1.1.7   root     1288:         gen_op_mov_TN_reg(ot, 0, d);
1.1       root     1289:     } else {
1.1.1.7   root     1290:         gen_op_ld_T0_A0(ot + s1->mem_index);
1.1       root     1291:     }
                   1292:     switch(op) {
                   1293:     case OP_ADCL:
1.1.1.7   root     1294:         if (s1->cc_op != CC_OP_DYNAMIC)
                   1295:             gen_op_set_cc_op(s1->cc_op);
                   1296:         gen_compute_eflags_c(cpu_tmp4);
                   1297:         tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
                   1298:         tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
                   1299:         if (d != OR_TMP0)
                   1300:             gen_op_mov_reg_T0(ot, d);
                   1301:         else
                   1302:             gen_op_st_T0_A0(ot + s1->mem_index);
                   1303:         tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
                   1304:         tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
                   1305:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp4);
                   1306:         tcg_gen_shli_i32(cpu_tmp2_i32, cpu_tmp2_i32, 2);
                   1307:         tcg_gen_addi_i32(cpu_cc_op, cpu_tmp2_i32, CC_OP_ADDB + ot);
                   1308:         s1->cc_op = CC_OP_DYNAMIC;
                   1309:         break;
1.1       root     1310:     case OP_SBBL:
                   1311:         if (s1->cc_op != CC_OP_DYNAMIC)
                   1312:             gen_op_set_cc_op(s1->cc_op);
1.1.1.7   root     1313:         gen_compute_eflags_c(cpu_tmp4);
                   1314:         tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
                   1315:         tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
                   1316:         if (d != OR_TMP0)
                   1317:             gen_op_mov_reg_T0(ot, d);
                   1318:         else
                   1319:             gen_op_st_T0_A0(ot + s1->mem_index);
                   1320:         tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
                   1321:         tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
                   1322:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp4);
                   1323:         tcg_gen_shli_i32(cpu_tmp2_i32, cpu_tmp2_i32, 2);
                   1324:         tcg_gen_addi_i32(cpu_cc_op, cpu_tmp2_i32, CC_OP_SUBB + ot);
1.1       root     1325:         s1->cc_op = CC_OP_DYNAMIC;
1.1.1.7   root     1326:         break;
1.1       root     1327:     case OP_ADDL:
                   1328:         gen_op_addl_T0_T1();
1.1.1.7   root     1329:         if (d != OR_TMP0)
                   1330:             gen_op_mov_reg_T0(ot, d);
                   1331:         else
                   1332:             gen_op_st_T0_A0(ot + s1->mem_index);
                   1333:         gen_op_update2_cc();
1.1       root     1334:         s1->cc_op = CC_OP_ADDB + ot;
                   1335:         break;
                   1336:     case OP_SUBL:
1.1.1.7   root     1337:         tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
                   1338:         if (d != OR_TMP0)
                   1339:             gen_op_mov_reg_T0(ot, d);
                   1340:         else
                   1341:             gen_op_st_T0_A0(ot + s1->mem_index);
                   1342:         gen_op_update2_cc();
1.1       root     1343:         s1->cc_op = CC_OP_SUBB + ot;
                   1344:         break;
                   1345:     default:
                   1346:     case OP_ANDL:
1.1.1.7   root     1347:         tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
                   1348:         if (d != OR_TMP0)
                   1349:             gen_op_mov_reg_T0(ot, d);
                   1350:         else
                   1351:             gen_op_st_T0_A0(ot + s1->mem_index);
                   1352:         gen_op_update1_cc();
                   1353:         s1->cc_op = CC_OP_LOGICB + ot;
                   1354:         break;
1.1       root     1355:     case OP_ORL:
1.1.1.7   root     1356:         tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
                   1357:         if (d != OR_TMP0)
                   1358:             gen_op_mov_reg_T0(ot, d);
                   1359:         else
                   1360:             gen_op_st_T0_A0(ot + s1->mem_index);
                   1361:         gen_op_update1_cc();
                   1362:         s1->cc_op = CC_OP_LOGICB + ot;
                   1363:         break;
1.1       root     1364:     case OP_XORL:
1.1.1.7   root     1365:         tcg_gen_xor_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();
1.1       root     1371:         s1->cc_op = CC_OP_LOGICB + ot;
                   1372:         break;
                   1373:     case OP_CMPL:
                   1374:         gen_op_cmpl_T0_T1_cc();
                   1375:         s1->cc_op = CC_OP_SUBB + ot;
                   1376:         break;
                   1377:     }
1.1.1.7   root     1378: }
                   1379: 
                   1380: /* if d == OR_TMP0, it means memory operand (address in A0) */
                   1381: static void gen_inc(DisasContext *s1, int ot, int d, int c)
                   1382: {
                   1383:     if (d != OR_TMP0)
                   1384:         gen_op_mov_TN_reg(ot, 0, d);
                   1385:     else
                   1386:         gen_op_ld_T0_A0(ot + s1->mem_index);
                   1387:     if (s1->cc_op != CC_OP_DYNAMIC)
                   1388:         gen_op_set_cc_op(s1->cc_op);
                   1389:     if (c > 0) {
                   1390:         tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 1);
                   1391:         s1->cc_op = CC_OP_INCB + ot;
                   1392:     } else {
                   1393:         tcg_gen_addi_tl(cpu_T[0], cpu_T[0], -1);
                   1394:         s1->cc_op = CC_OP_DECB + ot;
                   1395:     }
                   1396:     if (d != OR_TMP0)
                   1397:         gen_op_mov_reg_T0(ot, d);
                   1398:     else
                   1399:         gen_op_st_T0_A0(ot + s1->mem_index);
                   1400:     gen_compute_eflags_c(cpu_cc_src);
                   1401:     tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
                   1402: }
                   1403: 
                   1404: static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, 
                   1405:                             int is_right, int is_arith)
                   1406: {
                   1407:     target_ulong mask;
                   1408:     int shift_label;
1.1.1.16! root     1409:     TCGv t0, t1, t2;
1.1.1.7   root     1410: 
1.1.1.16! root     1411:     if (ot == OT_QUAD) {
1.1.1.7   root     1412:         mask = 0x3f;
1.1.1.16! root     1413:     } else {
1.1.1.7   root     1414:         mask = 0x1f;
1.1.1.16! root     1415:     }
1.1.1.7   root     1416: 
                   1417:     /* load */
1.1.1.16! root     1418:     if (op1 == OR_TMP0) {
1.1.1.7   root     1419:         gen_op_ld_T0_A0(ot + s->mem_index);
1.1.1.16! root     1420:     } else {
1.1.1.7   root     1421:         gen_op_mov_TN_reg(ot, 0, op1);
1.1.1.16! root     1422:     }
1.1.1.7   root     1423: 
1.1.1.16! root     1424:     t0 = tcg_temp_local_new();
        !          1425:     t1 = tcg_temp_local_new();
        !          1426:     t2 = tcg_temp_local_new();
1.1.1.7   root     1427: 
1.1.1.16! root     1428:     tcg_gen_andi_tl(t2, cpu_T[1], mask);
1.1.1.7   root     1429: 
                   1430:     if (is_right) {
                   1431:         if (is_arith) {
                   1432:             gen_exts(ot, cpu_T[0]);
1.1.1.16! root     1433:             tcg_gen_mov_tl(t0, cpu_T[0]);
        !          1434:             tcg_gen_sar_tl(cpu_T[0], cpu_T[0], t2);
1.1.1.7   root     1435:         } else {
                   1436:             gen_extu(ot, cpu_T[0]);
1.1.1.16! root     1437:             tcg_gen_mov_tl(t0, cpu_T[0]);
        !          1438:             tcg_gen_shr_tl(cpu_T[0], cpu_T[0], t2);
1.1.1.7   root     1439:         }
                   1440:     } else {
1.1.1.16! root     1441:         tcg_gen_mov_tl(t0, cpu_T[0]);
        !          1442:         tcg_gen_shl_tl(cpu_T[0], cpu_T[0], t2);
1.1.1.7   root     1443:     }
                   1444: 
                   1445:     /* store */
1.1.1.16! root     1446:     if (op1 == OR_TMP0) {
1.1.1.7   root     1447:         gen_op_st_T0_A0(ot + s->mem_index);
1.1.1.16! root     1448:     } else {
1.1.1.7   root     1449:         gen_op_mov_reg_T0(ot, op1);
1.1.1.16! root     1450:     }
        !          1451: 
1.1.1.7   root     1452:     /* update eflags if non zero shift */
1.1.1.16! root     1453:     if (s->cc_op != CC_OP_DYNAMIC) {
1.1.1.7   root     1454:         gen_op_set_cc_op(s->cc_op);
1.1.1.16! root     1455:     }
1.1.1.7   root     1456: 
1.1.1.16! root     1457:     tcg_gen_mov_tl(t1, cpu_T[0]);
1.1.1.7   root     1458: 
                   1459:     shift_label = gen_new_label();
1.1.1.16! root     1460:     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, shift_label);
1.1.1.7   root     1461: 
1.1.1.16! root     1462:     tcg_gen_addi_tl(t2, t2, -1);
        !          1463:     tcg_gen_mov_tl(cpu_cc_dst, t1);
        !          1464: 
        !          1465:     if (is_right) {
        !          1466:         if (is_arith) {
        !          1467:             tcg_gen_sar_tl(cpu_cc_src, t0, t2);
        !          1468:         } else {
        !          1469:             tcg_gen_shr_tl(cpu_cc_src, t0, t2);
        !          1470:         }
        !          1471:     } else {
        !          1472:         tcg_gen_shl_tl(cpu_cc_src, t0, t2);
        !          1473:     }
        !          1474: 
        !          1475:     if (is_right) {
1.1.1.7   root     1476:         tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
1.1.1.16! root     1477:     } else {
1.1.1.7   root     1478:         tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
1.1.1.16! root     1479:     }
        !          1480: 
1.1.1.7   root     1481:     gen_set_label(shift_label);
                   1482:     s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
                   1483: 
                   1484:     tcg_temp_free(t0);
                   1485:     tcg_temp_free(t1);
1.1.1.16! root     1486:     tcg_temp_free(t2);
1.1.1.7   root     1487: }
                   1488: 
                   1489: static void gen_shift_rm_im(DisasContext *s, int ot, int op1, int op2,
                   1490:                             int is_right, int is_arith)
                   1491: {
                   1492:     int mask;
                   1493:     
                   1494:     if (ot == OT_QUAD)
                   1495:         mask = 0x3f;
                   1496:     else
                   1497:         mask = 0x1f;
                   1498: 
                   1499:     /* load */
                   1500:     if (op1 == OR_TMP0)
                   1501:         gen_op_ld_T0_A0(ot + s->mem_index);
                   1502:     else
                   1503:         gen_op_mov_TN_reg(ot, 0, op1);
                   1504: 
                   1505:     op2 &= mask;
                   1506:     if (op2 != 0) {
                   1507:         if (is_right) {
                   1508:             if (is_arith) {
                   1509:                 gen_exts(ot, cpu_T[0]);
                   1510:                 tcg_gen_sari_tl(cpu_tmp4, cpu_T[0], op2 - 1);
                   1511:                 tcg_gen_sari_tl(cpu_T[0], cpu_T[0], op2);
                   1512:             } else {
                   1513:                 gen_extu(ot, cpu_T[0]);
                   1514:                 tcg_gen_shri_tl(cpu_tmp4, cpu_T[0], op2 - 1);
                   1515:                 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], op2);
                   1516:             }
                   1517:         } else {
                   1518:             tcg_gen_shli_tl(cpu_tmp4, cpu_T[0], op2 - 1);
                   1519:             tcg_gen_shli_tl(cpu_T[0], cpu_T[0], op2);
                   1520:         }
                   1521:     }
                   1522: 
                   1523:     /* store */
                   1524:     if (op1 == OR_TMP0)
                   1525:         gen_op_st_T0_A0(ot + s->mem_index);
                   1526:     else
                   1527:         gen_op_mov_reg_T0(ot, op1);
                   1528:         
                   1529:     /* update eflags if non zero shift */
                   1530:     if (op2 != 0) {
                   1531:         tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
                   1532:         tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
                   1533:         if (is_right)
                   1534:             s->cc_op = CC_OP_SARB + ot;
                   1535:         else
                   1536:             s->cc_op = CC_OP_SHLB + ot;
                   1537:     }
                   1538: }
                   1539: 
                   1540: static inline void tcg_gen_lshift(TCGv ret, TCGv arg1, target_long arg2)
                   1541: {
                   1542:     if (arg2 >= 0)
                   1543:         tcg_gen_shli_tl(ret, arg1, arg2);
                   1544:     else
                   1545:         tcg_gen_shri_tl(ret, arg1, -arg2);
                   1546: }
                   1547: 
                   1548: static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, 
                   1549:                           int is_right)
                   1550: {
                   1551:     target_ulong mask;
                   1552:     int label1, label2, data_bits;
                   1553:     TCGv t0, t1, t2, a0;
                   1554: 
                   1555:     /* XXX: inefficient, but we must use local temps */
                   1556:     t0 = tcg_temp_local_new();
                   1557:     t1 = tcg_temp_local_new();
                   1558:     t2 = tcg_temp_local_new();
                   1559:     a0 = tcg_temp_local_new();
                   1560: 
                   1561:     if (ot == OT_QUAD)
                   1562:         mask = 0x3f;
                   1563:     else
                   1564:         mask = 0x1f;
                   1565: 
                   1566:     /* load */
                   1567:     if (op1 == OR_TMP0) {
                   1568:         tcg_gen_mov_tl(a0, cpu_A0);
                   1569:         gen_op_ld_v(ot + s->mem_index, t0, a0);
                   1570:     } else {
                   1571:         gen_op_mov_v_reg(ot, t0, op1);
                   1572:     }
                   1573: 
                   1574:     tcg_gen_mov_tl(t1, cpu_T[1]);
                   1575: 
                   1576:     tcg_gen_andi_tl(t1, t1, mask);
                   1577: 
                   1578:     /* Must test zero case to avoid using undefined behaviour in TCG
                   1579:        shifts. */
                   1580:     label1 = gen_new_label();
                   1581:     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label1);
                   1582:     
                   1583:     if (ot <= OT_WORD)
                   1584:         tcg_gen_andi_tl(cpu_tmp0, t1, (1 << (3 + ot)) - 1);
                   1585:     else
                   1586:         tcg_gen_mov_tl(cpu_tmp0, t1);
                   1587:     
                   1588:     gen_extu(ot, t0);
                   1589:     tcg_gen_mov_tl(t2, t0);
                   1590: 
                   1591:     data_bits = 8 << ot;
                   1592:     /* XXX: rely on behaviour of shifts when operand 2 overflows (XXX:
                   1593:        fix TCG definition) */
                   1594:     if (is_right) {
                   1595:         tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp0);
1.1.1.9   root     1596:         tcg_gen_subfi_tl(cpu_tmp0, data_bits, cpu_tmp0);
1.1.1.7   root     1597:         tcg_gen_shl_tl(t0, t0, cpu_tmp0);
                   1598:     } else {
                   1599:         tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp0);
1.1.1.9   root     1600:         tcg_gen_subfi_tl(cpu_tmp0, data_bits, cpu_tmp0);
1.1.1.7   root     1601:         tcg_gen_shr_tl(t0, t0, cpu_tmp0);
                   1602:     }
                   1603:     tcg_gen_or_tl(t0, t0, cpu_tmp4);
                   1604: 
                   1605:     gen_set_label(label1);
                   1606:     /* store */
                   1607:     if (op1 == OR_TMP0) {
                   1608:         gen_op_st_v(ot + s->mem_index, t0, a0);
                   1609:     } else {
                   1610:         gen_op_mov_reg_v(ot, op1, t0);
1.1       root     1611:     }
1.1.1.7   root     1612:     
                   1613:     /* update eflags */
                   1614:     if (s->cc_op != CC_OP_DYNAMIC)
                   1615:         gen_op_set_cc_op(s->cc_op);
1.1       root     1616: 
1.1.1.7   root     1617:     label2 = gen_new_label();
                   1618:     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label2);
                   1619: 
                   1620:     gen_compute_eflags(cpu_cc_src);
                   1621:     tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
                   1622:     tcg_gen_xor_tl(cpu_tmp0, t2, t0);
                   1623:     tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
                   1624:     tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
                   1625:     tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
                   1626:     if (is_right) {
                   1627:         tcg_gen_shri_tl(t0, t0, data_bits - 1);
                   1628:     }
                   1629:     tcg_gen_andi_tl(t0, t0, CC_C);
                   1630:     tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
                   1631:     
                   1632:     tcg_gen_discard_tl(cpu_cc_dst);
                   1633:     tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
                   1634:         
                   1635:     gen_set_label(label2);
                   1636:     s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
                   1637: 
                   1638:     tcg_temp_free(t0);
                   1639:     tcg_temp_free(t1);
                   1640:     tcg_temp_free(t2);
                   1641:     tcg_temp_free(a0);
                   1642: }
                   1643: 
1.1.1.8   root     1644: static void gen_rot_rm_im(DisasContext *s, int ot, int op1, int op2,
                   1645:                           int is_right)
                   1646: {
                   1647:     int mask;
                   1648:     int data_bits;
                   1649:     TCGv t0, t1, a0;
                   1650: 
                   1651:     /* XXX: inefficient, but we must use local temps */
                   1652:     t0 = tcg_temp_local_new();
                   1653:     t1 = tcg_temp_local_new();
                   1654:     a0 = tcg_temp_local_new();
                   1655: 
                   1656:     if (ot == OT_QUAD)
                   1657:         mask = 0x3f;
                   1658:     else
                   1659:         mask = 0x1f;
                   1660: 
                   1661:     /* load */
                   1662:     if (op1 == OR_TMP0) {
                   1663:         tcg_gen_mov_tl(a0, cpu_A0);
                   1664:         gen_op_ld_v(ot + s->mem_index, t0, a0);
                   1665:     } else {
                   1666:         gen_op_mov_v_reg(ot, t0, op1);
                   1667:     }
                   1668: 
                   1669:     gen_extu(ot, t0);
                   1670:     tcg_gen_mov_tl(t1, t0);
                   1671: 
                   1672:     op2 &= mask;
                   1673:     data_bits = 8 << ot;
                   1674:     if (op2 != 0) {
                   1675:         int shift = op2 & ((1 << (3 + ot)) - 1);
                   1676:         if (is_right) {
                   1677:             tcg_gen_shri_tl(cpu_tmp4, t0, shift);
                   1678:             tcg_gen_shli_tl(t0, t0, data_bits - shift);
                   1679:         }
                   1680:         else {
                   1681:             tcg_gen_shli_tl(cpu_tmp4, t0, shift);
                   1682:             tcg_gen_shri_tl(t0, t0, data_bits - shift);
                   1683:         }
                   1684:         tcg_gen_or_tl(t0, t0, cpu_tmp4);
                   1685:     }
                   1686: 
                   1687:     /* store */
                   1688:     if (op1 == OR_TMP0) {
                   1689:         gen_op_st_v(ot + s->mem_index, t0, a0);
                   1690:     } else {
                   1691:         gen_op_mov_reg_v(ot, op1, t0);
                   1692:     }
                   1693: 
                   1694:     if (op2 != 0) {
                   1695:         /* update eflags */
                   1696:         if (s->cc_op != CC_OP_DYNAMIC)
                   1697:             gen_op_set_cc_op(s->cc_op);
                   1698: 
                   1699:         gen_compute_eflags(cpu_cc_src);
                   1700:         tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
                   1701:         tcg_gen_xor_tl(cpu_tmp0, t1, t0);
                   1702:         tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
                   1703:         tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
                   1704:         tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
                   1705:         if (is_right) {
                   1706:             tcg_gen_shri_tl(t0, t0, data_bits - 1);
                   1707:         }
                   1708:         tcg_gen_andi_tl(t0, t0, CC_C);
                   1709:         tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
                   1710: 
                   1711:         tcg_gen_discard_tl(cpu_cc_dst);
                   1712:         tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
                   1713:         s->cc_op = CC_OP_EFLAGS;
                   1714:     }
                   1715: 
                   1716:     tcg_temp_free(t0);
                   1717:     tcg_temp_free(t1);
                   1718:     tcg_temp_free(a0);
                   1719: }
                   1720: 
1.1.1.7   root     1721: /* XXX: add faster immediate = 1 case */
                   1722: static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, 
                   1723:                            int is_right)
1.1       root     1724: {
1.1.1.7   root     1725:     int label1;
                   1726: 
                   1727:     if (s->cc_op != CC_OP_DYNAMIC)
                   1728:         gen_op_set_cc_op(s->cc_op);
                   1729: 
                   1730:     /* load */
                   1731:     if (op1 == OR_TMP0)
                   1732:         gen_op_ld_T0_A0(ot + s->mem_index);
1.1       root     1733:     else
1.1.1.7   root     1734:         gen_op_mov_TN_reg(ot, 0, op1);
                   1735:     
                   1736:     if (is_right) {
                   1737:         switch (ot) {
                   1738:         case 0: gen_helper_rcrb(cpu_T[0], cpu_T[0], cpu_T[1]); break;
                   1739:         case 1: gen_helper_rcrw(cpu_T[0], cpu_T[0], cpu_T[1]); break;
                   1740:         case 2: gen_helper_rcrl(cpu_T[0], cpu_T[0], cpu_T[1]); break;
                   1741: #ifdef TARGET_X86_64
                   1742:         case 3: gen_helper_rcrq(cpu_T[0], cpu_T[0], cpu_T[1]); break;
                   1743: #endif
                   1744:         }
1.1       root     1745:     } else {
1.1.1.7   root     1746:         switch (ot) {
                   1747:         case 0: gen_helper_rclb(cpu_T[0], cpu_T[0], cpu_T[1]); break;
                   1748:         case 1: gen_helper_rclw(cpu_T[0], cpu_T[0], cpu_T[1]); break;
                   1749:         case 2: gen_helper_rcll(cpu_T[0], cpu_T[0], cpu_T[1]); break;
                   1750: #ifdef TARGET_X86_64
                   1751:         case 3: gen_helper_rclq(cpu_T[0], cpu_T[0], cpu_T[1]); break;
                   1752: #endif
                   1753:         }
1.1       root     1754:     }
1.1.1.7   root     1755:     /* store */
                   1756:     if (op1 == OR_TMP0)
                   1757:         gen_op_st_T0_A0(ot + s->mem_index);
                   1758:     else
                   1759:         gen_op_mov_reg_T0(ot, op1);
                   1760: 
                   1761:     /* update eflags */
                   1762:     label1 = gen_new_label();
                   1763:     tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cc_tmp, -1, label1);
                   1764: 
                   1765:     tcg_gen_mov_tl(cpu_cc_src, cpu_cc_tmp);
                   1766:     tcg_gen_discard_tl(cpu_cc_dst);
                   1767:     tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
                   1768:         
                   1769:     gen_set_label(label1);
                   1770:     s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
                   1771: }
                   1772: 
                   1773: /* XXX: add faster immediate case */
                   1774: static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1, 
                   1775:                                 int is_right)
                   1776: {
                   1777:     int label1, label2, data_bits;
                   1778:     target_ulong mask;
                   1779:     TCGv t0, t1, t2, a0;
                   1780: 
                   1781:     t0 = tcg_temp_local_new();
                   1782:     t1 = tcg_temp_local_new();
                   1783:     t2 = tcg_temp_local_new();
                   1784:     a0 = tcg_temp_local_new();
                   1785: 
                   1786:     if (ot == OT_QUAD)
                   1787:         mask = 0x3f;
1.1       root     1788:     else
1.1.1.7   root     1789:         mask = 0x1f;
                   1790: 
                   1791:     /* load */
                   1792:     if (op1 == OR_TMP0) {
                   1793:         tcg_gen_mov_tl(a0, cpu_A0);
                   1794:         gen_op_ld_v(ot + s->mem_index, t0, a0);
                   1795:     } else {
                   1796:         gen_op_mov_v_reg(ot, t0, op1);
                   1797:     }
                   1798: 
                   1799:     tcg_gen_andi_tl(cpu_T3, cpu_T3, mask);
                   1800: 
                   1801:     tcg_gen_mov_tl(t1, cpu_T[1]);
                   1802:     tcg_gen_mov_tl(t2, cpu_T3);
                   1803: 
                   1804:     /* Must test zero case to avoid using undefined behaviour in TCG
                   1805:        shifts. */
                   1806:     label1 = gen_new_label();
                   1807:     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
                   1808:     
                   1809:     tcg_gen_addi_tl(cpu_tmp5, t2, -1);
                   1810:     if (ot == OT_WORD) {
                   1811:         /* Note: we implement the Intel behaviour for shift count > 16 */
                   1812:         if (is_right) {
                   1813:             tcg_gen_andi_tl(t0, t0, 0xffff);
                   1814:             tcg_gen_shli_tl(cpu_tmp0, t1, 16);
                   1815:             tcg_gen_or_tl(t0, t0, cpu_tmp0);
                   1816:             tcg_gen_ext32u_tl(t0, t0);
                   1817: 
                   1818:             tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
                   1819:             
                   1820:             /* only needed if count > 16, but a test would complicate */
1.1.1.9   root     1821:             tcg_gen_subfi_tl(cpu_tmp5, 32, t2);
1.1.1.7   root     1822:             tcg_gen_shl_tl(cpu_tmp0, t0, cpu_tmp5);
                   1823: 
                   1824:             tcg_gen_shr_tl(t0, t0, t2);
                   1825: 
                   1826:             tcg_gen_or_tl(t0, t0, cpu_tmp0);
                   1827:         } else {
                   1828:             /* XXX: not optimal */
                   1829:             tcg_gen_andi_tl(t0, t0, 0xffff);
                   1830:             tcg_gen_shli_tl(t1, t1, 16);
                   1831:             tcg_gen_or_tl(t1, t1, t0);
                   1832:             tcg_gen_ext32u_tl(t1, t1);
                   1833:             
                   1834:             tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
1.1.1.9   root     1835:             tcg_gen_subfi_tl(cpu_tmp0, 32, cpu_tmp5);
                   1836:             tcg_gen_shr_tl(cpu_tmp5, t1, cpu_tmp0);
                   1837:             tcg_gen_or_tl(cpu_tmp4, cpu_tmp4, cpu_tmp5);
1.1.1.7   root     1838: 
                   1839:             tcg_gen_shl_tl(t0, t0, t2);
1.1.1.9   root     1840:             tcg_gen_subfi_tl(cpu_tmp5, 32, t2);
1.1.1.7   root     1841:             tcg_gen_shr_tl(t1, t1, cpu_tmp5);
                   1842:             tcg_gen_or_tl(t0, t0, t1);
                   1843:         }
                   1844:     } else {
                   1845:         data_bits = 8 << ot;
                   1846:         if (is_right) {
                   1847:             if (ot == OT_LONG)
                   1848:                 tcg_gen_ext32u_tl(t0, t0);
                   1849: 
                   1850:             tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
                   1851: 
                   1852:             tcg_gen_shr_tl(t0, t0, t2);
1.1.1.9   root     1853:             tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2);
1.1.1.7   root     1854:             tcg_gen_shl_tl(t1, t1, cpu_tmp5);
                   1855:             tcg_gen_or_tl(t0, t0, t1);
                   1856:             
                   1857:         } else {
                   1858:             if (ot == OT_LONG)
                   1859:                 tcg_gen_ext32u_tl(t1, t1);
                   1860: 
                   1861:             tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
                   1862:             
                   1863:             tcg_gen_shl_tl(t0, t0, t2);
1.1.1.9   root     1864:             tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2);
1.1.1.7   root     1865:             tcg_gen_shr_tl(t1, t1, cpu_tmp5);
                   1866:             tcg_gen_or_tl(t0, t0, t1);
                   1867:         }
                   1868:     }
                   1869:     tcg_gen_mov_tl(t1, cpu_tmp4);
                   1870: 
                   1871:     gen_set_label(label1);
                   1872:     /* store */
                   1873:     if (op1 == OR_TMP0) {
                   1874:         gen_op_st_v(ot + s->mem_index, t0, a0);
                   1875:     } else {
                   1876:         gen_op_mov_reg_v(ot, op1, t0);
                   1877:     }
                   1878:     
                   1879:     /* update eflags */
                   1880:     if (s->cc_op != CC_OP_DYNAMIC)
                   1881:         gen_op_set_cc_op(s->cc_op);
                   1882: 
                   1883:     label2 = gen_new_label();
                   1884:     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label2);
                   1885: 
                   1886:     tcg_gen_mov_tl(cpu_cc_src, t1);
                   1887:     tcg_gen_mov_tl(cpu_cc_dst, t0);
                   1888:     if (is_right) {
                   1889:         tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
                   1890:     } else {
                   1891:         tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
                   1892:     }
                   1893:     gen_set_label(label2);
                   1894:     s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
                   1895: 
                   1896:     tcg_temp_free(t0);
                   1897:     tcg_temp_free(t1);
                   1898:     tcg_temp_free(t2);
                   1899:     tcg_temp_free(a0);
1.1       root     1900: }
                   1901: 
                   1902: static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
                   1903: {
                   1904:     if (s != OR_TMP1)
1.1.1.7   root     1905:         gen_op_mov_TN_reg(ot, 1, s);
                   1906:     switch(op) {
                   1907:     case OP_ROL:
                   1908:         gen_rot_rm_T1(s1, ot, d, 0);
                   1909:         break;
                   1910:     case OP_ROR:
                   1911:         gen_rot_rm_T1(s1, ot, d, 1);
                   1912:         break;
                   1913:     case OP_SHL:
                   1914:     case OP_SHL1:
                   1915:         gen_shift_rm_T1(s1, ot, d, 0, 0);
                   1916:         break;
                   1917:     case OP_SHR:
                   1918:         gen_shift_rm_T1(s1, ot, d, 1, 0);
                   1919:         break;
                   1920:     case OP_SAR:
                   1921:         gen_shift_rm_T1(s1, ot, d, 1, 1);
                   1922:         break;
                   1923:     case OP_RCL:
                   1924:         gen_rotc_rm_T1(s1, ot, d, 0);
                   1925:         break;
                   1926:     case OP_RCR:
                   1927:         gen_rotc_rm_T1(s1, ot, d, 1);
                   1928:         break;
                   1929:     }
1.1       root     1930: }
                   1931: 
                   1932: static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
                   1933: {
1.1.1.7   root     1934:     switch(op) {
1.1.1.8   root     1935:     case OP_ROL:
                   1936:         gen_rot_rm_im(s1, ot, d, c, 0);
                   1937:         break;
                   1938:     case OP_ROR:
                   1939:         gen_rot_rm_im(s1, ot, d, c, 1);
                   1940:         break;
1.1.1.7   root     1941:     case OP_SHL:
                   1942:     case OP_SHL1:
                   1943:         gen_shift_rm_im(s1, ot, d, c, 0, 0);
                   1944:         break;
                   1945:     case OP_SHR:
                   1946:         gen_shift_rm_im(s1, ot, d, c, 1, 0);
                   1947:         break;
                   1948:     case OP_SAR:
                   1949:         gen_shift_rm_im(s1, ot, d, c, 1, 1);
                   1950:         break;
                   1951:     default:
                   1952:         /* currently not optimized */
                   1953:         gen_op_movl_T1_im(c);
                   1954:         gen_shift(s1, op, ot, d, OR_TMP1);
                   1955:         break;
                   1956:     }
1.1       root     1957: }
                   1958: 
                   1959: static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr)
                   1960: {
                   1961:     target_long disp;
                   1962:     int havesib;
                   1963:     int base;
                   1964:     int index;
                   1965:     int scale;
                   1966:     int opreg;
                   1967:     int mod, rm, code, override, must_add_seg;
                   1968: 
                   1969:     override = s->override;
                   1970:     must_add_seg = s->addseg;
                   1971:     if (override >= 0)
                   1972:         must_add_seg = 1;
                   1973:     mod = (modrm >> 6) & 3;
                   1974:     rm = modrm & 7;
                   1975: 
                   1976:     if (s->aflag) {
                   1977: 
                   1978:         havesib = 0;
                   1979:         base = rm;
                   1980:         index = 0;
                   1981:         scale = 0;
1.1.1.6   root     1982: 
1.1       root     1983:         if (base == 4) {
                   1984:             havesib = 1;
                   1985:             code = ldub_code(s->pc++);
                   1986:             scale = (code >> 6) & 3;
                   1987:             index = ((code >> 3) & 7) | REX_X(s);
                   1988:             base = (code & 7);
                   1989:         }
                   1990:         base |= REX_B(s);
                   1991: 
                   1992:         switch (mod) {
                   1993:         case 0:
                   1994:             if ((base & 7) == 5) {
                   1995:                 base = -1;
                   1996:                 disp = (int32_t)ldl_code(s->pc);
                   1997:                 s->pc += 4;
                   1998:                 if (CODE64(s) && !havesib) {
                   1999:                     disp += s->pc + s->rip_offset;
                   2000:                 }
                   2001:             } else {
                   2002:                 disp = 0;
                   2003:             }
                   2004:             break;
                   2005:         case 1:
                   2006:             disp = (int8_t)ldub_code(s->pc++);
                   2007:             break;
                   2008:         default:
                   2009:         case 2:
1.1.1.13  root     2010:             disp = (int32_t)ldl_code(s->pc);
1.1       root     2011:             s->pc += 4;
                   2012:             break;
                   2013:         }
1.1.1.6   root     2014: 
1.1       root     2015:         if (base >= 0) {
                   2016:             /* for correct popl handling with esp */
                   2017:             if (base == 4 && s->popl_esp_hack)
                   2018:                 disp += s->popl_esp_hack;
                   2019: #ifdef TARGET_X86_64
                   2020:             if (s->aflag == 2) {
1.1.1.7   root     2021:                 gen_op_movq_A0_reg(base);
1.1       root     2022:                 if (disp != 0) {
1.1.1.7   root     2023:                     gen_op_addq_A0_im(disp);
1.1       root     2024:                 }
1.1.1.6   root     2025:             } else
1.1       root     2026: #endif
                   2027:             {
1.1.1.7   root     2028:                 gen_op_movl_A0_reg(base);
1.1       root     2029:                 if (disp != 0)
                   2030:                     gen_op_addl_A0_im(disp);
                   2031:             }
                   2032:         } else {
                   2033: #ifdef TARGET_X86_64
                   2034:             if (s->aflag == 2) {
1.1.1.7   root     2035:                 gen_op_movq_A0_im(disp);
1.1.1.6   root     2036:             } else
1.1       root     2037: #endif
                   2038:             {
                   2039:                 gen_op_movl_A0_im(disp);
                   2040:             }
                   2041:         }
1.1.1.11  root     2042:         /* index == 4 means no index */
                   2043:         if (havesib && (index != 4)) {
1.1       root     2044: #ifdef TARGET_X86_64
                   2045:             if (s->aflag == 2) {
1.1.1.7   root     2046:                 gen_op_addq_A0_reg_sN(scale, index);
1.1.1.6   root     2047:             } else
1.1       root     2048: #endif
                   2049:             {
1.1.1.7   root     2050:                 gen_op_addl_A0_reg_sN(scale, index);
1.1       root     2051:             }
                   2052:         }
                   2053:         if (must_add_seg) {
                   2054:             if (override < 0) {
                   2055:                 if (base == R_EBP || base == R_ESP)
                   2056:                     override = R_SS;
                   2057:                 else
                   2058:                     override = R_DS;
                   2059:             }
                   2060: #ifdef TARGET_X86_64
                   2061:             if (s->aflag == 2) {
1.1.1.7   root     2062:                 gen_op_addq_A0_seg(override);
1.1.1.6   root     2063:             } else
1.1       root     2064: #endif
                   2065:             {
1.1.1.7   root     2066:                 gen_op_addl_A0_seg(override);
1.1       root     2067:             }
                   2068:         }
                   2069:     } else {
                   2070:         switch (mod) {
                   2071:         case 0:
                   2072:             if (rm == 6) {
                   2073:                 disp = lduw_code(s->pc);
                   2074:                 s->pc += 2;
                   2075:                 gen_op_movl_A0_im(disp);
                   2076:                 rm = 0; /* avoid SS override */
                   2077:                 goto no_rm;
                   2078:             } else {
                   2079:                 disp = 0;
                   2080:             }
                   2081:             break;
                   2082:         case 1:
                   2083:             disp = (int8_t)ldub_code(s->pc++);
                   2084:             break;
                   2085:         default:
                   2086:         case 2:
                   2087:             disp = lduw_code(s->pc);
                   2088:             s->pc += 2;
                   2089:             break;
                   2090:         }
                   2091:         switch(rm) {
                   2092:         case 0:
1.1.1.7   root     2093:             gen_op_movl_A0_reg(R_EBX);
                   2094:             gen_op_addl_A0_reg_sN(0, R_ESI);
1.1       root     2095:             break;
                   2096:         case 1:
1.1.1.7   root     2097:             gen_op_movl_A0_reg(R_EBX);
                   2098:             gen_op_addl_A0_reg_sN(0, R_EDI);
1.1       root     2099:             break;
                   2100:         case 2:
1.1.1.7   root     2101:             gen_op_movl_A0_reg(R_EBP);
                   2102:             gen_op_addl_A0_reg_sN(0, R_ESI);
1.1       root     2103:             break;
                   2104:         case 3:
1.1.1.7   root     2105:             gen_op_movl_A0_reg(R_EBP);
                   2106:             gen_op_addl_A0_reg_sN(0, R_EDI);
1.1       root     2107:             break;
                   2108:         case 4:
1.1.1.7   root     2109:             gen_op_movl_A0_reg(R_ESI);
1.1       root     2110:             break;
                   2111:         case 5:
1.1.1.7   root     2112:             gen_op_movl_A0_reg(R_EDI);
1.1       root     2113:             break;
                   2114:         case 6:
1.1.1.7   root     2115:             gen_op_movl_A0_reg(R_EBP);
1.1       root     2116:             break;
                   2117:         default:
                   2118:         case 7:
1.1.1.7   root     2119:             gen_op_movl_A0_reg(R_EBX);
1.1       root     2120:             break;
                   2121:         }
                   2122:         if (disp != 0)
                   2123:             gen_op_addl_A0_im(disp);
                   2124:         gen_op_andl_A0_ffff();
                   2125:     no_rm:
                   2126:         if (must_add_seg) {
                   2127:             if (override < 0) {
                   2128:                 if (rm == 2 || rm == 3 || rm == 6)
                   2129:                     override = R_SS;
                   2130:                 else
                   2131:                     override = R_DS;
                   2132:             }
1.1.1.7   root     2133:             gen_op_addl_A0_seg(override);
1.1       root     2134:         }
                   2135:     }
                   2136: 
                   2137:     opreg = OR_A0;
                   2138:     disp = 0;
                   2139:     *reg_ptr = opreg;
                   2140:     *offset_ptr = disp;
                   2141: }
                   2142: 
1.1.1.5   root     2143: static void gen_nop_modrm(DisasContext *s, int modrm)
                   2144: {
                   2145:     int mod, rm, base, code;
                   2146: 
                   2147:     mod = (modrm >> 6) & 3;
                   2148:     if (mod == 3)
                   2149:         return;
                   2150:     rm = modrm & 7;
                   2151: 
                   2152:     if (s->aflag) {
                   2153: 
                   2154:         base = rm;
1.1.1.6   root     2155: 
1.1.1.5   root     2156:         if (base == 4) {
                   2157:             code = ldub_code(s->pc++);
                   2158:             base = (code & 7);
                   2159:         }
1.1.1.6   root     2160: 
1.1.1.5   root     2161:         switch (mod) {
                   2162:         case 0:
                   2163:             if (base == 5) {
                   2164:                 s->pc += 4;
                   2165:             }
                   2166:             break;
                   2167:         case 1:
                   2168:             s->pc++;
                   2169:             break;
                   2170:         default:
                   2171:         case 2:
                   2172:             s->pc += 4;
                   2173:             break;
                   2174:         }
                   2175:     } else {
                   2176:         switch (mod) {
                   2177:         case 0:
                   2178:             if (rm == 6) {
                   2179:                 s->pc += 2;
                   2180:             }
                   2181:             break;
                   2182:         case 1:
                   2183:             s->pc++;
                   2184:             break;
                   2185:         default:
                   2186:         case 2:
                   2187:             s->pc += 2;
                   2188:             break;
                   2189:         }
                   2190:     }
                   2191: }
                   2192: 
1.1       root     2193: /* used for LEA and MOV AX, mem */
                   2194: static void gen_add_A0_ds_seg(DisasContext *s)
                   2195: {
                   2196:     int override, must_add_seg;
                   2197:     must_add_seg = s->addseg;
                   2198:     override = R_DS;
                   2199:     if (s->override >= 0) {
                   2200:         override = s->override;
                   2201:         must_add_seg = 1;
                   2202:     }
                   2203:     if (must_add_seg) {
                   2204: #ifdef TARGET_X86_64
                   2205:         if (CODE64(s)) {
1.1.1.7   root     2206:             gen_op_addq_A0_seg(override);
1.1.1.6   root     2207:         } else
1.1       root     2208: #endif
                   2209:         {
1.1.1.7   root     2210:             gen_op_addl_A0_seg(override);
1.1       root     2211:         }
                   2212:     }
                   2213: }
                   2214: 
1.1.1.7   root     2215: /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
1.1       root     2216:    OR_TMP0 */
                   2217: static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
                   2218: {
                   2219:     int mod, rm, opreg, disp;
                   2220: 
                   2221:     mod = (modrm >> 6) & 3;
                   2222:     rm = (modrm & 7) | REX_B(s);
                   2223:     if (mod == 3) {
                   2224:         if (is_store) {
                   2225:             if (reg != OR_TMP0)
1.1.1.7   root     2226:                 gen_op_mov_TN_reg(ot, 0, reg);
                   2227:             gen_op_mov_reg_T0(ot, rm);
1.1       root     2228:         } else {
1.1.1.7   root     2229:             gen_op_mov_TN_reg(ot, 0, rm);
1.1       root     2230:             if (reg != OR_TMP0)
1.1.1.7   root     2231:                 gen_op_mov_reg_T0(ot, reg);
1.1       root     2232:         }
                   2233:     } else {
                   2234:         gen_lea_modrm(s, modrm, &opreg, &disp);
                   2235:         if (is_store) {
                   2236:             if (reg != OR_TMP0)
1.1.1.7   root     2237:                 gen_op_mov_TN_reg(ot, 0, reg);
                   2238:             gen_op_st_T0_A0(ot + s->mem_index);
1.1       root     2239:         } else {
1.1.1.7   root     2240:             gen_op_ld_T0_A0(ot + s->mem_index);
1.1       root     2241:             if (reg != OR_TMP0)
1.1.1.7   root     2242:                 gen_op_mov_reg_T0(ot, reg);
1.1       root     2243:         }
                   2244:     }
                   2245: }
                   2246: 
                   2247: static inline uint32_t insn_get(DisasContext *s, int ot)
                   2248: {
                   2249:     uint32_t ret;
                   2250: 
                   2251:     switch(ot) {
                   2252:     case OT_BYTE:
                   2253:         ret = ldub_code(s->pc);
                   2254:         s->pc++;
                   2255:         break;
                   2256:     case OT_WORD:
                   2257:         ret = lduw_code(s->pc);
                   2258:         s->pc += 2;
                   2259:         break;
                   2260:     default:
                   2261:     case OT_LONG:
                   2262:         ret = ldl_code(s->pc);
                   2263:         s->pc += 4;
                   2264:         break;
                   2265:     }
                   2266:     return ret;
                   2267: }
                   2268: 
                   2269: static inline int insn_const_size(unsigned int ot)
                   2270: {
                   2271:     if (ot <= OT_LONG)
                   2272:         return 1 << ot;
                   2273:     else
                   2274:         return 4;
                   2275: }
                   2276: 
1.1.1.2   root     2277: static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
                   2278: {
                   2279:     TranslationBlock *tb;
                   2280:     target_ulong pc;
                   2281: 
                   2282:     pc = s->cs_base + eip;
                   2283:     tb = s->tb;
                   2284:     /* NOTE: we handle the case where the TB spans two pages here */
                   2285:     if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
                   2286:         (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
                   2287:         /* jump to same page: we can use a direct jump */
1.1.1.7   root     2288:         tcg_gen_goto_tb(tb_num);
1.1.1.2   root     2289:         gen_jmp_im(eip);
1.1.1.15  root     2290:         tcg_gen_exit_tb((tcg_target_long)tb + tb_num);
1.1.1.2   root     2291:     } else {
                   2292:         /* jump to another page: currently not optimized */
                   2293:         gen_jmp_im(eip);
                   2294:         gen_eob(s);
                   2295:     }
                   2296: }
                   2297: 
1.1.1.6   root     2298: static inline void gen_jcc(DisasContext *s, int b,
1.1       root     2299:                            target_ulong val, target_ulong next_eip)
                   2300: {
1.1.1.7   root     2301:     int l1, l2, cc_op;
1.1.1.6   root     2302: 
1.1.1.7   root     2303:     cc_op = s->cc_op;
1.1.1.13  root     2304:     gen_update_cc_op(s);
1.1       root     2305:     if (s->jmp_opt) {
                   2306:         l1 = gen_new_label();
1.1.1.7   root     2307:         gen_jcc1(s, cc_op, b, l1);
                   2308:         
1.1.1.2   root     2309:         gen_goto_tb(s, 0, next_eip);
1.1       root     2310: 
                   2311:         gen_set_label(l1);
1.1.1.2   root     2312:         gen_goto_tb(s, 1, val);
1.1.1.13  root     2313:         s->is_jmp = DISAS_TB_JUMP;
1.1       root     2314:     } else {
                   2315: 
                   2316:         l1 = gen_new_label();
                   2317:         l2 = gen_new_label();
1.1.1.7   root     2318:         gen_jcc1(s, cc_op, b, l1);
                   2319: 
1.1       root     2320:         gen_jmp_im(next_eip);
1.1.1.7   root     2321:         tcg_gen_br(l2);
                   2322: 
1.1       root     2323:         gen_set_label(l1);
                   2324:         gen_jmp_im(val);
                   2325:         gen_set_label(l2);
                   2326:         gen_eob(s);
                   2327:     }
                   2328: }
                   2329: 
                   2330: static void gen_setcc(DisasContext *s, int b)
                   2331: {
1.1.1.7   root     2332:     int inv, jcc_op, l1;
                   2333:     TCGv t0;
1.1.1.6   root     2334: 
1.1.1.7   root     2335:     if (is_fast_jcc_case(s, b)) {
                   2336:         /* nominal case: we use a jump */
                   2337:         /* XXX: make it faster by adding new instructions in TCG */
                   2338:         t0 = tcg_temp_local_new();
                   2339:         tcg_gen_movi_tl(t0, 0);
                   2340:         l1 = gen_new_label();
                   2341:         gen_jcc1(s, s->cc_op, b ^ 1, l1);
                   2342:         tcg_gen_movi_tl(t0, 1);
                   2343:         gen_set_label(l1);
                   2344:         tcg_gen_mov_tl(cpu_T[0], t0);
                   2345:         tcg_temp_free(t0);
                   2346:     } else {
                   2347:         /* slow case: it is more efficient not to generate a jump,
                   2348:            although it is questionnable whether this optimization is
                   2349:            worth to */
                   2350:         inv = b & 1;
                   2351:         jcc_op = (b >> 1) & 7;
                   2352:         gen_setcc_slow_T0(s, jcc_op);
                   2353:         if (inv) {
                   2354:             tcg_gen_xori_tl(cpu_T[0], cpu_T[0], 1);
1.1       root     2355:         }
                   2356:     }
                   2357: }
                   2358: 
1.1.1.7   root     2359: static inline void gen_op_movl_T0_seg(int seg_reg)
                   2360: {
                   2361:     tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
                   2362:                      offsetof(CPUX86State,segs[seg_reg].selector));
                   2363: }
                   2364: 
                   2365: static inline void gen_op_movl_seg_T0_vm(int seg_reg)
                   2366: {
                   2367:     tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
                   2368:     tcg_gen_st32_tl(cpu_T[0], cpu_env, 
                   2369:                     offsetof(CPUX86State,segs[seg_reg].selector));
                   2370:     tcg_gen_shli_tl(cpu_T[0], cpu_T[0], 4);
                   2371:     tcg_gen_st_tl(cpu_T[0], cpu_env, 
                   2372:                   offsetof(CPUX86State,segs[seg_reg].base));
                   2373: }
                   2374: 
1.1       root     2375: /* move T0 to seg_reg and compute if the CPU state may change. Never
                   2376:    call this function with seg_reg == R_CS */
                   2377: static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
                   2378: {
                   2379:     if (s->pe && !s->vm86) {
                   2380:         /* XXX: optimize by finding processor state dynamically */
                   2381:         if (s->cc_op != CC_OP_DYNAMIC)
                   2382:             gen_op_set_cc_op(s->cc_op);
                   2383:         gen_jmp_im(cur_eip);
1.1.1.7   root     2384:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   2385:         gen_helper_load_seg(tcg_const_i32(seg_reg), cpu_tmp2_i32);
1.1       root     2386:         /* abort translation because the addseg value may change or
                   2387:            because ss32 may change. For R_SS, translation must always
                   2388:            stop as a special handling must be done to disable hardware
                   2389:            interrupts for the next instruction */
                   2390:         if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
1.1.1.13  root     2391:             s->is_jmp = DISAS_TB_JUMP;
1.1       root     2392:     } else {
1.1.1.7   root     2393:         gen_op_movl_seg_T0_vm(seg_reg);
1.1       root     2394:         if (seg_reg == R_SS)
1.1.1.13  root     2395:             s->is_jmp = DISAS_TB_JUMP;
1.1       root     2396:     }
                   2397: }
                   2398: 
1.1.1.6   root     2399: static inline int svm_is_rep(int prefixes)
                   2400: {
                   2401:     return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
                   2402: }
                   2403: 
1.1.1.7   root     2404: static inline void
1.1.1.6   root     2405: gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
1.1.1.7   root     2406:                               uint32_t type, uint64_t param)
1.1.1.6   root     2407: {
1.1.1.7   root     2408:     /* no SVM activated; fast case */
                   2409:     if (likely(!(s->flags & HF_SVMI_MASK)))
                   2410:         return;
                   2411:     if (s->cc_op != CC_OP_DYNAMIC)
                   2412:         gen_op_set_cc_op(s->cc_op);
                   2413:     gen_jmp_im(pc_start - s->cs_base);
                   2414:     gen_helper_svm_check_intercept_param(tcg_const_i32(type),
                   2415:                                          tcg_const_i64(param));
1.1.1.6   root     2416: }
                   2417: 
1.1.1.7   root     2418: static inline void
1.1.1.6   root     2419: gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
                   2420: {
1.1.1.7   root     2421:     gen_svm_check_intercept_param(s, pc_start, type, 0);
1.1.1.6   root     2422: }
                   2423: 
1.1       root     2424: static inline void gen_stack_update(DisasContext *s, int addend)
                   2425: {
                   2426: #ifdef TARGET_X86_64
                   2427:     if (CODE64(s)) {
1.1.1.7   root     2428:         gen_op_add_reg_im(2, R_ESP, addend);
1.1       root     2429:     } else
                   2430: #endif
                   2431:     if (s->ss32) {
1.1.1.7   root     2432:         gen_op_add_reg_im(1, R_ESP, addend);
1.1       root     2433:     } else {
1.1.1.7   root     2434:         gen_op_add_reg_im(0, R_ESP, addend);
1.1       root     2435:     }
                   2436: }
                   2437: 
                   2438: /* generate a push. It depends on ss32, addseg and dflag */
                   2439: static void gen_push_T0(DisasContext *s)
                   2440: {
                   2441: #ifdef TARGET_X86_64
                   2442:     if (CODE64(s)) {
1.1.1.7   root     2443:         gen_op_movq_A0_reg(R_ESP);
1.1       root     2444:         if (s->dflag) {
1.1.1.7   root     2445:             gen_op_addq_A0_im(-8);
                   2446:             gen_op_st_T0_A0(OT_QUAD + s->mem_index);
1.1       root     2447:         } else {
1.1.1.7   root     2448:             gen_op_addq_A0_im(-2);
                   2449:             gen_op_st_T0_A0(OT_WORD + s->mem_index);
1.1       root     2450:         }
1.1.1.7   root     2451:         gen_op_mov_reg_A0(2, R_ESP);
1.1.1.6   root     2452:     } else
1.1       root     2453: #endif
                   2454:     {
1.1.1.7   root     2455:         gen_op_movl_A0_reg(R_ESP);
1.1       root     2456:         if (!s->dflag)
1.1.1.7   root     2457:             gen_op_addl_A0_im(-2);
1.1       root     2458:         else
1.1.1.7   root     2459:             gen_op_addl_A0_im(-4);
1.1       root     2460:         if (s->ss32) {
                   2461:             if (s->addseg) {
1.1.1.7   root     2462:                 tcg_gen_mov_tl(cpu_T[1], cpu_A0);
                   2463:                 gen_op_addl_A0_seg(R_SS);
1.1       root     2464:             }
                   2465:         } else {
                   2466:             gen_op_andl_A0_ffff();
1.1.1.7   root     2467:             tcg_gen_mov_tl(cpu_T[1], cpu_A0);
                   2468:             gen_op_addl_A0_seg(R_SS);
1.1       root     2469:         }
1.1.1.7   root     2470:         gen_op_st_T0_A0(s->dflag + 1 + s->mem_index);
1.1       root     2471:         if (s->ss32 && !s->addseg)
1.1.1.7   root     2472:             gen_op_mov_reg_A0(1, R_ESP);
1.1       root     2473:         else
1.1.1.7   root     2474:             gen_op_mov_reg_T1(s->ss32 + 1, R_ESP);
1.1       root     2475:     }
                   2476: }
                   2477: 
                   2478: /* generate a push. It depends on ss32, addseg and dflag */
                   2479: /* slower version for T1, only used for call Ev */
                   2480: static void gen_push_T1(DisasContext *s)
                   2481: {
                   2482: #ifdef TARGET_X86_64
                   2483:     if (CODE64(s)) {
1.1.1.7   root     2484:         gen_op_movq_A0_reg(R_ESP);
1.1       root     2485:         if (s->dflag) {
1.1.1.7   root     2486:             gen_op_addq_A0_im(-8);
                   2487:             gen_op_st_T1_A0(OT_QUAD + s->mem_index);
1.1       root     2488:         } else {
1.1.1.7   root     2489:             gen_op_addq_A0_im(-2);
                   2490:             gen_op_st_T0_A0(OT_WORD + s->mem_index);
1.1       root     2491:         }
1.1.1.7   root     2492:         gen_op_mov_reg_A0(2, R_ESP);
1.1.1.6   root     2493:     } else
1.1       root     2494: #endif
                   2495:     {
1.1.1.7   root     2496:         gen_op_movl_A0_reg(R_ESP);
1.1       root     2497:         if (!s->dflag)
1.1.1.7   root     2498:             gen_op_addl_A0_im(-2);
1.1       root     2499:         else
1.1.1.7   root     2500:             gen_op_addl_A0_im(-4);
1.1       root     2501:         if (s->ss32) {
                   2502:             if (s->addseg) {
1.1.1.7   root     2503:                 gen_op_addl_A0_seg(R_SS);
1.1       root     2504:             }
                   2505:         } else {
                   2506:             gen_op_andl_A0_ffff();
1.1.1.7   root     2507:             gen_op_addl_A0_seg(R_SS);
1.1       root     2508:         }
1.1.1.7   root     2509:         gen_op_st_T1_A0(s->dflag + 1 + s->mem_index);
1.1.1.6   root     2510: 
1.1       root     2511:         if (s->ss32 && !s->addseg)
1.1.1.7   root     2512:             gen_op_mov_reg_A0(1, R_ESP);
1.1       root     2513:         else
                   2514:             gen_stack_update(s, (-2) << s->dflag);
                   2515:     }
                   2516: }
                   2517: 
                   2518: /* two step pop is necessary for precise exceptions */
                   2519: static void gen_pop_T0(DisasContext *s)
                   2520: {
                   2521: #ifdef TARGET_X86_64
                   2522:     if (CODE64(s)) {
1.1.1.7   root     2523:         gen_op_movq_A0_reg(R_ESP);
                   2524:         gen_op_ld_T0_A0((s->dflag ? OT_QUAD : OT_WORD) + s->mem_index);
1.1.1.6   root     2525:     } else
1.1       root     2526: #endif
                   2527:     {
1.1.1.7   root     2528:         gen_op_movl_A0_reg(R_ESP);
1.1       root     2529:         if (s->ss32) {
                   2530:             if (s->addseg)
1.1.1.7   root     2531:                 gen_op_addl_A0_seg(R_SS);
1.1       root     2532:         } else {
                   2533:             gen_op_andl_A0_ffff();
1.1.1.7   root     2534:             gen_op_addl_A0_seg(R_SS);
1.1       root     2535:         }
1.1.1.7   root     2536:         gen_op_ld_T0_A0(s->dflag + 1 + s->mem_index);
1.1       root     2537:     }
                   2538: }
                   2539: 
                   2540: static void gen_pop_update(DisasContext *s)
                   2541: {
                   2542: #ifdef TARGET_X86_64
                   2543:     if (CODE64(s) && s->dflag) {
                   2544:         gen_stack_update(s, 8);
                   2545:     } else
                   2546: #endif
                   2547:     {
                   2548:         gen_stack_update(s, 2 << s->dflag);
                   2549:     }
                   2550: }
                   2551: 
                   2552: static void gen_stack_A0(DisasContext *s)
                   2553: {
1.1.1.7   root     2554:     gen_op_movl_A0_reg(R_ESP);
1.1       root     2555:     if (!s->ss32)
                   2556:         gen_op_andl_A0_ffff();
1.1.1.7   root     2557:     tcg_gen_mov_tl(cpu_T[1], cpu_A0);
1.1       root     2558:     if (s->addseg)
1.1.1.7   root     2559:         gen_op_addl_A0_seg(R_SS);
1.1       root     2560: }
                   2561: 
                   2562: /* NOTE: wrap around in 16 bit not fully handled */
                   2563: static void gen_pusha(DisasContext *s)
                   2564: {
                   2565:     int i;
1.1.1.7   root     2566:     gen_op_movl_A0_reg(R_ESP);
1.1       root     2567:     gen_op_addl_A0_im(-16 <<  s->dflag);
                   2568:     if (!s->ss32)
                   2569:         gen_op_andl_A0_ffff();
1.1.1.7   root     2570:     tcg_gen_mov_tl(cpu_T[1], cpu_A0);
1.1       root     2571:     if (s->addseg)
1.1.1.7   root     2572:         gen_op_addl_A0_seg(R_SS);
1.1       root     2573:     for(i = 0;i < 8; i++) {
1.1.1.7   root     2574:         gen_op_mov_TN_reg(OT_LONG, 0, 7 - i);
                   2575:         gen_op_st_T0_A0(OT_WORD + s->dflag + s->mem_index);
1.1       root     2576:         gen_op_addl_A0_im(2 <<  s->dflag);
                   2577:     }
1.1.1.7   root     2578:     gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
1.1       root     2579: }
                   2580: 
                   2581: /* NOTE: wrap around in 16 bit not fully handled */
                   2582: static void gen_popa(DisasContext *s)
                   2583: {
                   2584:     int i;
1.1.1.7   root     2585:     gen_op_movl_A0_reg(R_ESP);
1.1       root     2586:     if (!s->ss32)
                   2587:         gen_op_andl_A0_ffff();
1.1.1.7   root     2588:     tcg_gen_mov_tl(cpu_T[1], cpu_A0);
                   2589:     tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 16 <<  s->dflag);
1.1       root     2590:     if (s->addseg)
1.1.1.7   root     2591:         gen_op_addl_A0_seg(R_SS);
1.1       root     2592:     for(i = 0;i < 8; i++) {
                   2593:         /* ESP is not reloaded */
                   2594:         if (i != 3) {
1.1.1.7   root     2595:             gen_op_ld_T0_A0(OT_WORD + s->dflag + s->mem_index);
                   2596:             gen_op_mov_reg_T0(OT_WORD + s->dflag, 7 - i);
1.1       root     2597:         }
                   2598:         gen_op_addl_A0_im(2 <<  s->dflag);
                   2599:     }
1.1.1.7   root     2600:     gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
1.1       root     2601: }
                   2602: 
                   2603: static void gen_enter(DisasContext *s, int esp_addend, int level)
                   2604: {
                   2605:     int ot, opsize;
                   2606: 
                   2607:     level &= 0x1f;
                   2608: #ifdef TARGET_X86_64
                   2609:     if (CODE64(s)) {
                   2610:         ot = s->dflag ? OT_QUAD : OT_WORD;
                   2611:         opsize = 1 << ot;
1.1.1.6   root     2612: 
1.1.1.7   root     2613:         gen_op_movl_A0_reg(R_ESP);
1.1       root     2614:         gen_op_addq_A0_im(-opsize);
1.1.1.7   root     2615:         tcg_gen_mov_tl(cpu_T[1], cpu_A0);
1.1       root     2616: 
                   2617:         /* push bp */
1.1.1.7   root     2618:         gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
                   2619:         gen_op_st_T0_A0(ot + s->mem_index);
1.1       root     2620:         if (level) {
1.1.1.7   root     2621:             /* XXX: must save state */
                   2622:             gen_helper_enter64_level(tcg_const_i32(level),
                   2623:                                      tcg_const_i32((ot == OT_QUAD)),
                   2624:                                      cpu_T[1]);
                   2625:         }
                   2626:         gen_op_mov_reg_T1(ot, R_EBP);
                   2627:         tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
                   2628:         gen_op_mov_reg_T1(OT_QUAD, R_ESP);
1.1.1.6   root     2629:     } else
1.1       root     2630: #endif
                   2631:     {
                   2632:         ot = s->dflag + OT_WORD;
                   2633:         opsize = 2 << s->dflag;
1.1.1.6   root     2634: 
1.1.1.7   root     2635:         gen_op_movl_A0_reg(R_ESP);
1.1       root     2636:         gen_op_addl_A0_im(-opsize);
                   2637:         if (!s->ss32)
                   2638:             gen_op_andl_A0_ffff();
1.1.1.7   root     2639:         tcg_gen_mov_tl(cpu_T[1], cpu_A0);
1.1       root     2640:         if (s->addseg)
1.1.1.7   root     2641:             gen_op_addl_A0_seg(R_SS);
1.1       root     2642:         /* push bp */
1.1.1.7   root     2643:         gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
                   2644:         gen_op_st_T0_A0(ot + s->mem_index);
1.1       root     2645:         if (level) {
1.1.1.7   root     2646:             /* XXX: must save state */
                   2647:             gen_helper_enter_level(tcg_const_i32(level),
                   2648:                                    tcg_const_i32(s->dflag),
                   2649:                                    cpu_T[1]);
                   2650:         }
                   2651:         gen_op_mov_reg_T1(ot, R_EBP);
                   2652:         tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
                   2653:         gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
1.1       root     2654:     }
                   2655: }
                   2656: 
                   2657: static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
                   2658: {
                   2659:     if (s->cc_op != CC_OP_DYNAMIC)
                   2660:         gen_op_set_cc_op(s->cc_op);
                   2661:     gen_jmp_im(cur_eip);
1.1.1.7   root     2662:     gen_helper_raise_exception(tcg_const_i32(trapno));
1.1.1.13  root     2663:     s->is_jmp = DISAS_TB_JUMP;
1.1       root     2664: }
                   2665: 
                   2666: /* an interrupt is different from an exception because of the
1.1.1.6   root     2667:    privilege checks */
                   2668: static void gen_interrupt(DisasContext *s, int intno,
1.1       root     2669:                           target_ulong cur_eip, target_ulong next_eip)
                   2670: {
                   2671:     if (s->cc_op != CC_OP_DYNAMIC)
                   2672:         gen_op_set_cc_op(s->cc_op);
                   2673:     gen_jmp_im(cur_eip);
1.1.1.7   root     2674:     gen_helper_raise_interrupt(tcg_const_i32(intno), 
                   2675:                                tcg_const_i32(next_eip - cur_eip));
1.1.1.13  root     2676:     s->is_jmp = DISAS_TB_JUMP;
1.1       root     2677: }
                   2678: 
                   2679: static void gen_debug(DisasContext *s, target_ulong cur_eip)
                   2680: {
                   2681:     if (s->cc_op != CC_OP_DYNAMIC)
                   2682:         gen_op_set_cc_op(s->cc_op);
                   2683:     gen_jmp_im(cur_eip);
1.1.1.7   root     2684:     gen_helper_debug();
1.1.1.13  root     2685:     s->is_jmp = DISAS_TB_JUMP;
1.1       root     2686: }
                   2687: 
                   2688: /* generate a generic end of block. Trace exception is also generated
                   2689:    if needed */
                   2690: static void gen_eob(DisasContext *s)
                   2691: {
                   2692:     if (s->cc_op != CC_OP_DYNAMIC)
                   2693:         gen_op_set_cc_op(s->cc_op);
                   2694:     if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
1.1.1.7   root     2695:         gen_helper_reset_inhibit_irq();
1.1       root     2696:     }
1.1.1.8   root     2697:     if (s->tb->flags & HF_RF_MASK) {
                   2698:         gen_helper_reset_rf();
                   2699:     }
1.1       root     2700:     if (s->singlestep_enabled) {
1.1.1.7   root     2701:         gen_helper_debug();
1.1       root     2702:     } else if (s->tf) {
1.1.1.7   root     2703:        gen_helper_single_step();
1.1       root     2704:     } else {
1.1.1.7   root     2705:         tcg_gen_exit_tb(0);
1.1       root     2706:     }
1.1.1.13  root     2707:     s->is_jmp = DISAS_TB_JUMP;
1.1       root     2708: }
                   2709: 
                   2710: /* generate a jump to eip. No segment change must happen before as a
                   2711:    direct call to the next block may occur */
                   2712: static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
                   2713: {
                   2714:     if (s->jmp_opt) {
1.1.1.13  root     2715:         gen_update_cc_op(s);
1.1.1.2   root     2716:         gen_goto_tb(s, tb_num, eip);
1.1.1.13  root     2717:         s->is_jmp = DISAS_TB_JUMP;
1.1       root     2718:     } else {
                   2719:         gen_jmp_im(eip);
                   2720:         gen_eob(s);
                   2721:     }
                   2722: }
                   2723: 
                   2724: static void gen_jmp(DisasContext *s, target_ulong eip)
                   2725: {
                   2726:     gen_jmp_tb(s, eip, 0);
                   2727: }
                   2728: 
1.1.1.7   root     2729: static inline void gen_ldq_env_A0(int idx, int offset)
1.1       root     2730: {
1.1.1.7   root     2731:     int mem_index = (idx >> 2) - 1;
                   2732:     tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
                   2733:     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
1.1       root     2734: }
                   2735: 
1.1.1.7   root     2736: static inline void gen_stq_env_A0(int idx, int offset)
1.1       root     2737: {
1.1.1.7   root     2738:     int mem_index = (idx >> 2) - 1;
                   2739:     tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
                   2740:     tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
1.1       root     2741: }
                   2742: 
1.1.1.7   root     2743: static inline void gen_ldo_env_A0(int idx, int offset)
1.1       root     2744: {
1.1.1.7   root     2745:     int mem_index = (idx >> 2) - 1;
                   2746:     tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
                   2747:     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
                   2748:     tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
                   2749:     tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_tmp0, mem_index);
                   2750:     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
1.1       root     2751: }
                   2752: 
1.1.1.7   root     2753: static inline void gen_sto_env_A0(int idx, int offset)
                   2754: {
                   2755:     int mem_index = (idx >> 2) - 1;
                   2756:     tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
                   2757:     tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
                   2758:     tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
                   2759:     tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
                   2760:     tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_tmp0, mem_index);
                   2761: }
1.1       root     2762: 
1.1.1.7   root     2763: static inline void gen_op_movo(int d_offset, int s_offset)
                   2764: {
                   2765:     tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
                   2766:     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
                   2767:     tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + 8);
                   2768:     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + 8);
                   2769: }
1.1       root     2770: 
1.1.1.7   root     2771: static inline void gen_op_movq(int d_offset, int s_offset)
                   2772: {
                   2773:     tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
                   2774:     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
                   2775: }
1.1       root     2776: 
1.1.1.7   root     2777: static inline void gen_op_movl(int d_offset, int s_offset)
                   2778: {
                   2779:     tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
                   2780:     tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
                   2781: }
                   2782: 
                   2783: static inline void gen_op_movq_env_0(int d_offset)
                   2784: {
                   2785:     tcg_gen_movi_i64(cpu_tmp1_i64, 0);
                   2786:     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
                   2787: }
1.1       root     2788: 
1.1.1.7   root     2789: #define SSE_SPECIAL ((void *)1)
                   2790: #define SSE_DUMMY ((void *)2)
1.1       root     2791: 
1.1.1.7   root     2792: #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
                   2793: #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
                   2794:                      gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
1.1       root     2795: 
1.1.1.7   root     2796: static void *sse_op_table1[256][4] = {
                   2797:     /* 3DNow! extensions */
                   2798:     [0x0e] = { SSE_DUMMY }, /* femms */
                   2799:     [0x0f] = { SSE_DUMMY }, /* pf... */
1.1       root     2800:     /* pure SSE operations */
                   2801:     [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
                   2802:     [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
1.1.1.3   root     2803:     [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
1.1       root     2804:     [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
1.1.1.7   root     2805:     [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
                   2806:     [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
1.1       root     2807:     [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */
                   2808:     [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */
                   2809: 
                   2810:     [0x28] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
                   2811:     [0x29] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
                   2812:     [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
1.1.1.9   root     2813:     [0x2b] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd, movntss, movntsd */
1.1       root     2814:     [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
                   2815:     [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
1.1.1.7   root     2816:     [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd },
                   2817:     [0x2f] = { gen_helper_comiss, gen_helper_comisd },
1.1       root     2818:     [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
                   2819:     [0x51] = SSE_FOP(sqrt),
1.1.1.7   root     2820:     [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL },
                   2821:     [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL },
                   2822:     [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */
                   2823:     [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */
                   2824:     [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */
                   2825:     [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */
1.1       root     2826:     [0x58] = SSE_FOP(add),
                   2827:     [0x59] = SSE_FOP(mul),
1.1.1.7   root     2828:     [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps,
                   2829:                gen_helper_cvtss2sd, gen_helper_cvtsd2ss },
                   2830:     [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq },
1.1       root     2831:     [0x5c] = SSE_FOP(sub),
                   2832:     [0x5d] = SSE_FOP(min),
                   2833:     [0x5e] = SSE_FOP(div),
                   2834:     [0x5f] = SSE_FOP(max),
                   2835: 
                   2836:     [0xc2] = SSE_FOP(cmpeq),
1.1.1.7   root     2837:     [0xc6] = { gen_helper_shufps, gen_helper_shufpd },
                   2838: 
                   2839:     [0x38] = { SSE_SPECIAL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* SSSE3/SSE4 */
                   2840:     [0x3a] = { SSE_SPECIAL, SSE_SPECIAL }, /* SSSE3/SSE4 */
1.1       root     2841: 
                   2842:     /* MMX ops and their SSE extensions */
                   2843:     [0x60] = MMX_OP2(punpcklbw),
                   2844:     [0x61] = MMX_OP2(punpcklwd),
                   2845:     [0x62] = MMX_OP2(punpckldq),
                   2846:     [0x63] = MMX_OP2(packsswb),
                   2847:     [0x64] = MMX_OP2(pcmpgtb),
                   2848:     [0x65] = MMX_OP2(pcmpgtw),
                   2849:     [0x66] = MMX_OP2(pcmpgtl),
                   2850:     [0x67] = MMX_OP2(packuswb),
                   2851:     [0x68] = MMX_OP2(punpckhbw),
                   2852:     [0x69] = MMX_OP2(punpckhwd),
                   2853:     [0x6a] = MMX_OP2(punpckhdq),
                   2854:     [0x6b] = MMX_OP2(packssdw),
1.1.1.7   root     2855:     [0x6c] = { NULL, gen_helper_punpcklqdq_xmm },
                   2856:     [0x6d] = { NULL, gen_helper_punpckhqdq_xmm },
1.1       root     2857:     [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
                   2858:     [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
1.1.1.7   root     2859:     [0x70] = { gen_helper_pshufw_mmx,
                   2860:                gen_helper_pshufd_xmm,
                   2861:                gen_helper_pshufhw_xmm,
                   2862:                gen_helper_pshuflw_xmm },
1.1       root     2863:     [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
                   2864:     [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
                   2865:     [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
                   2866:     [0x74] = MMX_OP2(pcmpeqb),
                   2867:     [0x75] = MMX_OP2(pcmpeqw),
                   2868:     [0x76] = MMX_OP2(pcmpeql),
1.1.1.7   root     2869:     [0x77] = { SSE_DUMMY }, /* emms */
1.1.1.9   root     2870:     [0x78] = { NULL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* extrq_i, insertq_i */
                   2871:     [0x79] = { NULL, gen_helper_extrq_r, NULL, gen_helper_insertq_r },
1.1.1.7   root     2872:     [0x7c] = { NULL, gen_helper_haddpd, NULL, gen_helper_haddps },
                   2873:     [0x7d] = { NULL, gen_helper_hsubpd, NULL, gen_helper_hsubps },
1.1       root     2874:     [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
                   2875:     [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
                   2876:     [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
                   2877:     [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
1.1.1.7   root     2878:     [0xd0] = { NULL, gen_helper_addsubpd, NULL, gen_helper_addsubps },
1.1       root     2879:     [0xd1] = MMX_OP2(psrlw),
                   2880:     [0xd2] = MMX_OP2(psrld),
                   2881:     [0xd3] = MMX_OP2(psrlq),
                   2882:     [0xd4] = MMX_OP2(paddq),
                   2883:     [0xd5] = MMX_OP2(pmullw),
                   2884:     [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
                   2885:     [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
                   2886:     [0xd8] = MMX_OP2(psubusb),
                   2887:     [0xd9] = MMX_OP2(psubusw),
                   2888:     [0xda] = MMX_OP2(pminub),
                   2889:     [0xdb] = MMX_OP2(pand),
                   2890:     [0xdc] = MMX_OP2(paddusb),
                   2891:     [0xdd] = MMX_OP2(paddusw),
                   2892:     [0xde] = MMX_OP2(pmaxub),
                   2893:     [0xdf] = MMX_OP2(pandn),
                   2894:     [0xe0] = MMX_OP2(pavgb),
                   2895:     [0xe1] = MMX_OP2(psraw),
                   2896:     [0xe2] = MMX_OP2(psrad),
                   2897:     [0xe3] = MMX_OP2(pavgw),
                   2898:     [0xe4] = MMX_OP2(pmulhuw),
                   2899:     [0xe5] = MMX_OP2(pmulhw),
1.1.1.7   root     2900:     [0xe6] = { NULL, gen_helper_cvttpd2dq, gen_helper_cvtdq2pd, gen_helper_cvtpd2dq },
1.1       root     2901:     [0xe7] = { SSE_SPECIAL , SSE_SPECIAL },  /* movntq, movntq */
                   2902:     [0xe8] = MMX_OP2(psubsb),
                   2903:     [0xe9] = MMX_OP2(psubsw),
                   2904:     [0xea] = MMX_OP2(pminsw),
                   2905:     [0xeb] = MMX_OP2(por),
                   2906:     [0xec] = MMX_OP2(paddsb),
                   2907:     [0xed] = MMX_OP2(paddsw),
                   2908:     [0xee] = MMX_OP2(pmaxsw),
                   2909:     [0xef] = MMX_OP2(pxor),
1.1.1.3   root     2910:     [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
1.1       root     2911:     [0xf1] = MMX_OP2(psllw),
                   2912:     [0xf2] = MMX_OP2(pslld),
                   2913:     [0xf3] = MMX_OP2(psllq),
                   2914:     [0xf4] = MMX_OP2(pmuludq),
                   2915:     [0xf5] = MMX_OP2(pmaddwd),
                   2916:     [0xf6] = MMX_OP2(psadbw),
                   2917:     [0xf7] = MMX_OP2(maskmov),
                   2918:     [0xf8] = MMX_OP2(psubb),
                   2919:     [0xf9] = MMX_OP2(psubw),
                   2920:     [0xfa] = MMX_OP2(psubl),
                   2921:     [0xfb] = MMX_OP2(psubq),
                   2922:     [0xfc] = MMX_OP2(paddb),
                   2923:     [0xfd] = MMX_OP2(paddw),
                   2924:     [0xfe] = MMX_OP2(paddl),
                   2925: };
                   2926: 
1.1.1.7   root     2927: static void *sse_op_table2[3 * 8][2] = {
1.1       root     2928:     [0 + 2] = MMX_OP2(psrlw),
                   2929:     [0 + 4] = MMX_OP2(psraw),
                   2930:     [0 + 6] = MMX_OP2(psllw),
                   2931:     [8 + 2] = MMX_OP2(psrld),
                   2932:     [8 + 4] = MMX_OP2(psrad),
                   2933:     [8 + 6] = MMX_OP2(pslld),
                   2934:     [16 + 2] = MMX_OP2(psrlq),
1.1.1.7   root     2935:     [16 + 3] = { NULL, gen_helper_psrldq_xmm },
1.1       root     2936:     [16 + 6] = MMX_OP2(psllq),
1.1.1.7   root     2937:     [16 + 7] = { NULL, gen_helper_pslldq_xmm },
1.1       root     2938: };
                   2939: 
1.1.1.7   root     2940: static void *sse_op_table3[4 * 3] = {
                   2941:     gen_helper_cvtsi2ss,
                   2942:     gen_helper_cvtsi2sd,
                   2943:     X86_64_ONLY(gen_helper_cvtsq2ss),
                   2944:     X86_64_ONLY(gen_helper_cvtsq2sd),
                   2945: 
                   2946:     gen_helper_cvttss2si,
                   2947:     gen_helper_cvttsd2si,
                   2948:     X86_64_ONLY(gen_helper_cvttss2sq),
                   2949:     X86_64_ONLY(gen_helper_cvttsd2sq),
                   2950: 
                   2951:     gen_helper_cvtss2si,
                   2952:     gen_helper_cvtsd2si,
                   2953:     X86_64_ONLY(gen_helper_cvtss2sq),
                   2954:     X86_64_ONLY(gen_helper_cvtsd2sq),
1.1       root     2955: };
1.1.1.6   root     2956: 
1.1.1.7   root     2957: static void *sse_op_table4[8][4] = {
1.1       root     2958:     SSE_FOP(cmpeq),
                   2959:     SSE_FOP(cmplt),
                   2960:     SSE_FOP(cmple),
                   2961:     SSE_FOP(cmpunord),
                   2962:     SSE_FOP(cmpneq),
                   2963:     SSE_FOP(cmpnlt),
                   2964:     SSE_FOP(cmpnle),
                   2965:     SSE_FOP(cmpord),
                   2966: };
1.1.1.6   root     2967: 
1.1.1.7   root     2968: static void *sse_op_table5[256] = {
                   2969:     [0x0c] = gen_helper_pi2fw,
                   2970:     [0x0d] = gen_helper_pi2fd,
                   2971:     [0x1c] = gen_helper_pf2iw,
                   2972:     [0x1d] = gen_helper_pf2id,
                   2973:     [0x8a] = gen_helper_pfnacc,
                   2974:     [0x8e] = gen_helper_pfpnacc,
                   2975:     [0x90] = gen_helper_pfcmpge,
                   2976:     [0x94] = gen_helper_pfmin,
                   2977:     [0x96] = gen_helper_pfrcp,
                   2978:     [0x97] = gen_helper_pfrsqrt,
                   2979:     [0x9a] = gen_helper_pfsub,
                   2980:     [0x9e] = gen_helper_pfadd,
                   2981:     [0xa0] = gen_helper_pfcmpgt,
                   2982:     [0xa4] = gen_helper_pfmax,
                   2983:     [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
                   2984:     [0xa7] = gen_helper_movq, /* pfrsqit1 */
                   2985:     [0xaa] = gen_helper_pfsubr,
                   2986:     [0xae] = gen_helper_pfacc,
                   2987:     [0xb0] = gen_helper_pfcmpeq,
                   2988:     [0xb4] = gen_helper_pfmul,
                   2989:     [0xb6] = gen_helper_movq, /* pfrcpit2 */
                   2990:     [0xb7] = gen_helper_pmulhrw_mmx,
                   2991:     [0xbb] = gen_helper_pswapd,
                   2992:     [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
                   2993: };
                   2994: 
                   2995: struct sse_op_helper_s {
                   2996:     void *op[2]; uint32_t ext_mask;
                   2997: };
                   2998: #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
                   2999: #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
                   3000: #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
                   3001: #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
                   3002: static struct sse_op_helper_s sse_op_table6[256] = {
                   3003:     [0x00] = SSSE3_OP(pshufb),
                   3004:     [0x01] = SSSE3_OP(phaddw),
                   3005:     [0x02] = SSSE3_OP(phaddd),
                   3006:     [0x03] = SSSE3_OP(phaddsw),
                   3007:     [0x04] = SSSE3_OP(pmaddubsw),
                   3008:     [0x05] = SSSE3_OP(phsubw),
                   3009:     [0x06] = SSSE3_OP(phsubd),
                   3010:     [0x07] = SSSE3_OP(phsubsw),
                   3011:     [0x08] = SSSE3_OP(psignb),
                   3012:     [0x09] = SSSE3_OP(psignw),
                   3013:     [0x0a] = SSSE3_OP(psignd),
                   3014:     [0x0b] = SSSE3_OP(pmulhrsw),
                   3015:     [0x10] = SSE41_OP(pblendvb),
                   3016:     [0x14] = SSE41_OP(blendvps),
                   3017:     [0x15] = SSE41_OP(blendvpd),
                   3018:     [0x17] = SSE41_OP(ptest),
                   3019:     [0x1c] = SSSE3_OP(pabsb),
                   3020:     [0x1d] = SSSE3_OP(pabsw),
                   3021:     [0x1e] = SSSE3_OP(pabsd),
                   3022:     [0x20] = SSE41_OP(pmovsxbw),
                   3023:     [0x21] = SSE41_OP(pmovsxbd),
                   3024:     [0x22] = SSE41_OP(pmovsxbq),
                   3025:     [0x23] = SSE41_OP(pmovsxwd),
                   3026:     [0x24] = SSE41_OP(pmovsxwq),
                   3027:     [0x25] = SSE41_OP(pmovsxdq),
                   3028:     [0x28] = SSE41_OP(pmuldq),
                   3029:     [0x29] = SSE41_OP(pcmpeqq),
                   3030:     [0x2a] = SSE41_SPECIAL, /* movntqda */
                   3031:     [0x2b] = SSE41_OP(packusdw),
                   3032:     [0x30] = SSE41_OP(pmovzxbw),
                   3033:     [0x31] = SSE41_OP(pmovzxbd),
                   3034:     [0x32] = SSE41_OP(pmovzxbq),
                   3035:     [0x33] = SSE41_OP(pmovzxwd),
                   3036:     [0x34] = SSE41_OP(pmovzxwq),
                   3037:     [0x35] = SSE41_OP(pmovzxdq),
                   3038:     [0x37] = SSE42_OP(pcmpgtq),
                   3039:     [0x38] = SSE41_OP(pminsb),
                   3040:     [0x39] = SSE41_OP(pminsd),
                   3041:     [0x3a] = SSE41_OP(pminuw),
                   3042:     [0x3b] = SSE41_OP(pminud),
                   3043:     [0x3c] = SSE41_OP(pmaxsb),
                   3044:     [0x3d] = SSE41_OP(pmaxsd),
                   3045:     [0x3e] = SSE41_OP(pmaxuw),
                   3046:     [0x3f] = SSE41_OP(pmaxud),
                   3047:     [0x40] = SSE41_OP(pmulld),
                   3048:     [0x41] = SSE41_OP(phminposuw),
                   3049: };
                   3050: 
                   3051: static struct sse_op_helper_s sse_op_table7[256] = {
                   3052:     [0x08] = SSE41_OP(roundps),
                   3053:     [0x09] = SSE41_OP(roundpd),
                   3054:     [0x0a] = SSE41_OP(roundss),
                   3055:     [0x0b] = SSE41_OP(roundsd),
                   3056:     [0x0c] = SSE41_OP(blendps),
                   3057:     [0x0d] = SSE41_OP(blendpd),
                   3058:     [0x0e] = SSE41_OP(pblendw),
                   3059:     [0x0f] = SSSE3_OP(palignr),
                   3060:     [0x14] = SSE41_SPECIAL, /* pextrb */
                   3061:     [0x15] = SSE41_SPECIAL, /* pextrw */
                   3062:     [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */
                   3063:     [0x17] = SSE41_SPECIAL, /* extractps */
                   3064:     [0x20] = SSE41_SPECIAL, /* pinsrb */
                   3065:     [0x21] = SSE41_SPECIAL, /* insertps */
                   3066:     [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */
                   3067:     [0x40] = SSE41_OP(dpps),
                   3068:     [0x41] = SSE41_OP(dppd),
                   3069:     [0x42] = SSE41_OP(mpsadbw),
                   3070:     [0x60] = SSE42_OP(pcmpestrm),
                   3071:     [0x61] = SSE42_OP(pcmpestri),
                   3072:     [0x62] = SSE42_OP(pcmpistrm),
                   3073:     [0x63] = SSE42_OP(pcmpistri),
                   3074: };
                   3075: 
1.1       root     3076: static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
                   3077: {
                   3078:     int b1, op1_offset, op2_offset, is_xmm, val, ot;
                   3079:     int modrm, mod, rm, reg, reg_addr, offset_addr;
1.1.1.7   root     3080:     void *sse_op2;
1.1       root     3081: 
                   3082:     b &= 0xff;
1.1.1.6   root     3083:     if (s->prefix & PREFIX_DATA)
1.1       root     3084:         b1 = 1;
1.1.1.6   root     3085:     else if (s->prefix & PREFIX_REPZ)
1.1       root     3086:         b1 = 2;
1.1.1.6   root     3087:     else if (s->prefix & PREFIX_REPNZ)
1.1       root     3088:         b1 = 3;
                   3089:     else
                   3090:         b1 = 0;
                   3091:     sse_op2 = sse_op_table1[b][b1];
1.1.1.6   root     3092:     if (!sse_op2)
1.1       root     3093:         goto illegal_op;
1.1.1.7   root     3094:     if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
1.1       root     3095:         is_xmm = 1;
                   3096:     } else {
                   3097:         if (b1 == 0) {
                   3098:             /* MMX case */
                   3099:             is_xmm = 0;
                   3100:         } else {
                   3101:             is_xmm = 1;
                   3102:         }
                   3103:     }
                   3104:     /* simple MMX/SSE operation */
                   3105:     if (s->flags & HF_TS_MASK) {
                   3106:         gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
                   3107:         return;
                   3108:     }
                   3109:     if (s->flags & HF_EM_MASK) {
                   3110:     illegal_op:
                   3111:         gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
                   3112:         return;
                   3113:     }
                   3114:     if (is_xmm && !(s->flags & HF_OSFXSR_MASK))
1.1.1.7   root     3115:         if ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))
                   3116:             goto illegal_op;
                   3117:     if (b == 0x0e) {
                   3118:         if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
                   3119:             goto illegal_op;
                   3120:         /* femms */
                   3121:         gen_helper_emms();
                   3122:         return;
                   3123:     }
1.1       root     3124:     if (b == 0x77) {
                   3125:         /* emms */
1.1.1.7   root     3126:         gen_helper_emms();
1.1       root     3127:         return;
                   3128:     }
                   3129:     /* prepare MMX state (XXX: optimize by storing fptt and fptags in
                   3130:        the static cpu state) */
                   3131:     if (!is_xmm) {
1.1.1.7   root     3132:         gen_helper_enter_mmx();
1.1       root     3133:     }
                   3134: 
                   3135:     modrm = ldub_code(s->pc++);
                   3136:     reg = ((modrm >> 3) & 7);
                   3137:     if (is_xmm)
                   3138:         reg |= rex_r;
                   3139:     mod = (modrm >> 6) & 3;
                   3140:     if (sse_op2 == SSE_SPECIAL) {
                   3141:         b |= (b1 << 8);
                   3142:         switch(b) {
                   3143:         case 0x0e7: /* movntq */
1.1.1.6   root     3144:             if (mod == 3)
1.1       root     3145:                 goto illegal_op;
                   3146:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3147:             gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
1.1       root     3148:             break;
                   3149:         case 0x1e7: /* movntdq */
                   3150:         case 0x02b: /* movntps */
                   3151:         case 0x12b: /* movntps */
1.1.1.3   root     3152:             if (mod == 3)
1.1       root     3153:                 goto illegal_op;
                   3154:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3155:             gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
1.1       root     3156:             break;
1.1.1.11  root     3157:         case 0x3f0: /* lddqu */
                   3158:             if (mod == 3)
                   3159:                 goto illegal_op;
                   3160:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3161:             gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
                   3162:             break;
1.1.1.9   root     3163:         case 0x22b: /* movntss */
                   3164:         case 0x32b: /* movntsd */
                   3165:             if (mod == 3)
                   3166:                 goto illegal_op;
                   3167:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3168:             if (b1 & 1) {
                   3169:                 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,
                   3170:                     xmm_regs[reg]));
                   3171:             } else {
                   3172:                 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
                   3173:                     xmm_regs[reg].XMM_L(0)));
                   3174:                 gen_op_st_T0_A0(OT_LONG + s->mem_index);
                   3175:             }
                   3176:             break;
1.1       root     3177:         case 0x6e: /* movd mm, ea */
1.1.1.5   root     3178: #ifdef TARGET_X86_64
                   3179:             if (s->dflag == 2) {
                   3180:                 gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
1.1.1.7   root     3181:                 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,fpregs[reg].mmx));
1.1.1.6   root     3182:             } else
1.1.1.5   root     3183: #endif
                   3184:             {
                   3185:                 gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
1.1.1.7   root     3186:                 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
                   3187:                                  offsetof(CPUX86State,fpregs[reg].mmx));
                   3188:                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   3189:                 gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32);
1.1.1.5   root     3190:             }
1.1       root     3191:             break;
                   3192:         case 0x16e: /* movd xmm, ea */
1.1.1.5   root     3193: #ifdef TARGET_X86_64
                   3194:             if (s->dflag == 2) {
                   3195:                 gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
1.1.1.7   root     3196:                 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
                   3197:                                  offsetof(CPUX86State,xmm_regs[reg]));
                   3198:                 gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T[0]);
1.1.1.6   root     3199:             } else
1.1.1.5   root     3200: #endif
                   3201:             {
                   3202:                 gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
1.1.1.7   root     3203:                 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
                   3204:                                  offsetof(CPUX86State,xmm_regs[reg]));
                   3205:                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   3206:                 gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32);
1.1.1.5   root     3207:             }
1.1       root     3208:             break;
                   3209:         case 0x6f: /* movq mm, ea */
                   3210:             if (mod != 3) {
                   3211:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3212:                 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
1.1       root     3213:             } else {
                   3214:                 rm = (modrm & 7);
1.1.1.7   root     3215:                 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
                   3216:                                offsetof(CPUX86State,fpregs[rm].mmx));
                   3217:                 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
                   3218:                                offsetof(CPUX86State,fpregs[reg].mmx));
1.1       root     3219:             }
                   3220:             break;
                   3221:         case 0x010: /* movups */
                   3222:         case 0x110: /* movupd */
                   3223:         case 0x028: /* movaps */
                   3224:         case 0x128: /* movapd */
                   3225:         case 0x16f: /* movdqa xmm, ea */
                   3226:         case 0x26f: /* movdqu xmm, ea */
                   3227:             if (mod != 3) {
                   3228:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3229:                 gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
1.1       root     3230:             } else {
                   3231:                 rm = (modrm & 7) | REX_B(s);
                   3232:                 gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
                   3233:                             offsetof(CPUX86State,xmm_regs[rm]));
                   3234:             }
                   3235:             break;
                   3236:         case 0x210: /* movss xmm, ea */
                   3237:             if (mod != 3) {
                   3238:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3239:                 gen_op_ld_T0_A0(OT_LONG + s->mem_index);
                   3240:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
1.1       root     3241:                 gen_op_movl_T0_0();
1.1.1.7   root     3242:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
                   3243:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
                   3244:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
1.1       root     3245:             } else {
                   3246:                 rm = (modrm & 7) | REX_B(s);
                   3247:                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
                   3248:                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
                   3249:             }
                   3250:             break;
                   3251:         case 0x310: /* movsd xmm, ea */
                   3252:             if (mod != 3) {
                   3253:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3254:                 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
1.1       root     3255:                 gen_op_movl_T0_0();
1.1.1.7   root     3256:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
                   3257:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
1.1       root     3258:             } else {
                   3259:                 rm = (modrm & 7) | REX_B(s);
                   3260:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
                   3261:                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
                   3262:             }
                   3263:             break;
                   3264:         case 0x012: /* movlps */
                   3265:         case 0x112: /* movlpd */
                   3266:             if (mod != 3) {
                   3267:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3268:                 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
1.1       root     3269:             } else {
                   3270:                 /* movhlps */
                   3271:                 rm = (modrm & 7) | REX_B(s);
                   3272:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
                   3273:                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
                   3274:             }
                   3275:             break;
1.1.1.3   root     3276:         case 0x212: /* movsldup */
                   3277:             if (mod != 3) {
                   3278:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3279:                 gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
1.1.1.3   root     3280:             } else {
                   3281:                 rm = (modrm & 7) | REX_B(s);
                   3282:                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
                   3283:                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
                   3284:                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
                   3285:                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(2)));
                   3286:             }
                   3287:             gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
                   3288:                         offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
                   3289:             gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
                   3290:                         offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
                   3291:             break;
                   3292:         case 0x312: /* movddup */
                   3293:             if (mod != 3) {
                   3294:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3295:                 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
1.1.1.3   root     3296:             } else {
                   3297:                 rm = (modrm & 7) | REX_B(s);
                   3298:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
                   3299:                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
                   3300:             }
                   3301:             gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
                   3302:                         offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
                   3303:             break;
1.1       root     3304:         case 0x016: /* movhps */
                   3305:         case 0x116: /* movhpd */
                   3306:             if (mod != 3) {
                   3307:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3308:                 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
1.1       root     3309:             } else {
                   3310:                 /* movlhps */
                   3311:                 rm = (modrm & 7) | REX_B(s);
                   3312:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
                   3313:                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
                   3314:             }
                   3315:             break;
                   3316:         case 0x216: /* movshdup */
                   3317:             if (mod != 3) {
                   3318:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3319:                 gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
1.1       root     3320:             } else {
                   3321:                 rm = (modrm & 7) | REX_B(s);
                   3322:                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
                   3323:                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(1)));
                   3324:                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
                   3325:                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(3)));
                   3326:             }
                   3327:             gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
                   3328:                         offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
                   3329:             gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
                   3330:                         offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
                   3331:             break;
1.1.1.9   root     3332:         case 0x178:
                   3333:         case 0x378:
                   3334:             {
                   3335:                 int bit_index, field_length;
                   3336: 
                   3337:                 if (b1 == 1 && reg != 0)
                   3338:                     goto illegal_op;
                   3339:                 field_length = ldub_code(s->pc++) & 0x3F;
                   3340:                 bit_index = ldub_code(s->pc++) & 0x3F;
                   3341:                 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
                   3342:                     offsetof(CPUX86State,xmm_regs[reg]));
                   3343:                 if (b1 == 1)
                   3344:                     gen_helper_extrq_i(cpu_ptr0, tcg_const_i32(bit_index),
                   3345:                         tcg_const_i32(field_length));
                   3346:                 else
                   3347:                     gen_helper_insertq_i(cpu_ptr0, tcg_const_i32(bit_index),
                   3348:                         tcg_const_i32(field_length));
                   3349:             }
                   3350:             break;
1.1       root     3351:         case 0x7e: /* movd ea, mm */
1.1.1.5   root     3352: #ifdef TARGET_X86_64
                   3353:             if (s->dflag == 2) {
1.1.1.7   root     3354:                 tcg_gen_ld_i64(cpu_T[0], cpu_env, 
                   3355:                                offsetof(CPUX86State,fpregs[reg].mmx));
1.1.1.5   root     3356:                 gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1);
1.1.1.6   root     3357:             } else
1.1.1.5   root     3358: #endif
                   3359:             {
1.1.1.7   root     3360:                 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
                   3361:                                  offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0)));
1.1.1.5   root     3362:                 gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
                   3363:             }
1.1       root     3364:             break;
                   3365:         case 0x17e: /* movd ea, xmm */
1.1.1.5   root     3366: #ifdef TARGET_X86_64
                   3367:             if (s->dflag == 2) {
1.1.1.7   root     3368:                 tcg_gen_ld_i64(cpu_T[0], cpu_env, 
                   3369:                                offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
1.1.1.5   root     3370:                 gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1);
1.1.1.6   root     3371:             } else
1.1.1.5   root     3372: #endif
                   3373:             {
1.1.1.7   root     3374:                 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
                   3375:                                  offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
1.1.1.5   root     3376:                 gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
                   3377:             }
1.1       root     3378:             break;
                   3379:         case 0x27e: /* movq xmm, ea */
                   3380:             if (mod != 3) {
                   3381:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3382:                 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
1.1       root     3383:             } else {
                   3384:                 rm = (modrm & 7) | REX_B(s);
                   3385:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
                   3386:                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
                   3387:             }
                   3388:             gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
                   3389:             break;
                   3390:         case 0x7f: /* movq ea, mm */
                   3391:             if (mod != 3) {
                   3392:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3393:                 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
1.1       root     3394:             } else {
                   3395:                 rm = (modrm & 7);
                   3396:                 gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
                   3397:                             offsetof(CPUX86State,fpregs[reg].mmx));
                   3398:             }
                   3399:             break;
                   3400:         case 0x011: /* movups */
                   3401:         case 0x111: /* movupd */
                   3402:         case 0x029: /* movaps */
                   3403:         case 0x129: /* movapd */
                   3404:         case 0x17f: /* movdqa ea, xmm */
                   3405:         case 0x27f: /* movdqu ea, xmm */
                   3406:             if (mod != 3) {
                   3407:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3408:                 gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
1.1       root     3409:             } else {
                   3410:                 rm = (modrm & 7) | REX_B(s);
                   3411:                 gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
                   3412:                             offsetof(CPUX86State,xmm_regs[reg]));
                   3413:             }
                   3414:             break;
                   3415:         case 0x211: /* movss ea, xmm */
                   3416:             if (mod != 3) {
                   3417:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3418:                 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
                   3419:                 gen_op_st_T0_A0(OT_LONG + s->mem_index);
1.1       root     3420:             } else {
                   3421:                 rm = (modrm & 7) | REX_B(s);
                   3422:                 gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)),
                   3423:                             offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
                   3424:             }
                   3425:             break;
                   3426:         case 0x311: /* movsd ea, xmm */
                   3427:             if (mod != 3) {
                   3428:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3429:                 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
1.1       root     3430:             } else {
                   3431:                 rm = (modrm & 7) | REX_B(s);
                   3432:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
                   3433:                             offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
                   3434:             }
                   3435:             break;
                   3436:         case 0x013: /* movlps */
                   3437:         case 0x113: /* movlpd */
                   3438:             if (mod != 3) {
                   3439:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3440:                 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
1.1       root     3441:             } else {
                   3442:                 goto illegal_op;
                   3443:             }
                   3444:             break;
                   3445:         case 0x017: /* movhps */
                   3446:         case 0x117: /* movhpd */
                   3447:             if (mod != 3) {
                   3448:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3449:                 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
1.1       root     3450:             } else {
                   3451:                 goto illegal_op;
                   3452:             }
                   3453:             break;
                   3454:         case 0x71: /* shift mm, im */
                   3455:         case 0x72:
                   3456:         case 0x73:
                   3457:         case 0x171: /* shift xmm, im */
                   3458:         case 0x172:
                   3459:         case 0x173:
1.1.1.13  root     3460:             if (b1 >= 2) {
                   3461:                goto illegal_op;
                   3462:             }
1.1       root     3463:             val = ldub_code(s->pc++);
                   3464:             if (is_xmm) {
                   3465:                 gen_op_movl_T0_im(val);
1.1.1.7   root     3466:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
1.1       root     3467:                 gen_op_movl_T0_0();
1.1.1.7   root     3468:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(1)));
1.1       root     3469:                 op1_offset = offsetof(CPUX86State,xmm_t0);
                   3470:             } else {
                   3471:                 gen_op_movl_T0_im(val);
1.1.1.7   root     3472:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0)));
1.1       root     3473:                 gen_op_movl_T0_0();
1.1.1.7   root     3474:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1)));
1.1       root     3475:                 op1_offset = offsetof(CPUX86State,mmx_t0);
                   3476:             }
                   3477:             sse_op2 = sse_op_table2[((b - 1) & 3) * 8 + (((modrm >> 3)) & 7)][b1];
                   3478:             if (!sse_op2)
                   3479:                 goto illegal_op;
                   3480:             if (is_xmm) {
                   3481:                 rm = (modrm & 7) | REX_B(s);
                   3482:                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
                   3483:             } else {
                   3484:                 rm = (modrm & 7);
                   3485:                 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
                   3486:             }
1.1.1.7   root     3487:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
                   3488:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset);
                   3489:             ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
1.1       root     3490:             break;
                   3491:         case 0x050: /* movmskps */
                   3492:             rm = (modrm & 7) | REX_B(s);
1.1.1.7   root     3493:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
                   3494:                              offsetof(CPUX86State,xmm_regs[rm]));
                   3495:             gen_helper_movmskps(cpu_tmp2_i32, cpu_ptr0);
                   3496:             tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
                   3497:             gen_op_mov_reg_T0(OT_LONG, reg);
1.1       root     3498:             break;
                   3499:         case 0x150: /* movmskpd */
                   3500:             rm = (modrm & 7) | REX_B(s);
1.1.1.7   root     3501:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
                   3502:                              offsetof(CPUX86State,xmm_regs[rm]));
                   3503:             gen_helper_movmskpd(cpu_tmp2_i32, cpu_ptr0);
                   3504:             tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
                   3505:             gen_op_mov_reg_T0(OT_LONG, reg);
1.1       root     3506:             break;
                   3507:         case 0x02a: /* cvtpi2ps */
                   3508:         case 0x12a: /* cvtpi2pd */
1.1.1.7   root     3509:             gen_helper_enter_mmx();
1.1       root     3510:             if (mod != 3) {
                   3511:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3512:                 op2_offset = offsetof(CPUX86State,mmx_t0);
1.1.1.7   root     3513:                 gen_ldq_env_A0(s->mem_index, op2_offset);
1.1       root     3514:             } else {
                   3515:                 rm = (modrm & 7);
                   3516:                 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
                   3517:             }
                   3518:             op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
1.1.1.7   root     3519:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
                   3520:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
1.1       root     3521:             switch(b >> 8) {
                   3522:             case 0x0:
1.1.1.7   root     3523:                 gen_helper_cvtpi2ps(cpu_ptr0, cpu_ptr1);
1.1       root     3524:                 break;
                   3525:             default:
                   3526:             case 0x1:
1.1.1.7   root     3527:                 gen_helper_cvtpi2pd(cpu_ptr0, cpu_ptr1);
1.1       root     3528:                 break;
                   3529:             }
                   3530:             break;
                   3531:         case 0x22a: /* cvtsi2ss */
                   3532:         case 0x32a: /* cvtsi2sd */
                   3533:             ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
                   3534:             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
                   3535:             op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
1.1.1.7   root     3536:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
                   3537:             sse_op2 = sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2)];
                   3538:             if (ot == OT_LONG) {
                   3539:                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   3540:                 ((void (*)(TCGv_ptr, TCGv_i32))sse_op2)(cpu_ptr0, cpu_tmp2_i32);
                   3541:             } else {
                   3542:                 ((void (*)(TCGv_ptr, TCGv))sse_op2)(cpu_ptr0, cpu_T[0]);
                   3543:             }
1.1       root     3544:             break;
                   3545:         case 0x02c: /* cvttps2pi */
                   3546:         case 0x12c: /* cvttpd2pi */
                   3547:         case 0x02d: /* cvtps2pi */
                   3548:         case 0x12d: /* cvtpd2pi */
1.1.1.7   root     3549:             gen_helper_enter_mmx();
1.1       root     3550:             if (mod != 3) {
                   3551:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3552:                 op2_offset = offsetof(CPUX86State,xmm_t0);
1.1.1.7   root     3553:                 gen_ldo_env_A0(s->mem_index, op2_offset);
1.1       root     3554:             } else {
                   3555:                 rm = (modrm & 7) | REX_B(s);
                   3556:                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
                   3557:             }
                   3558:             op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
1.1.1.7   root     3559:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
                   3560:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
1.1       root     3561:             switch(b) {
                   3562:             case 0x02c:
1.1.1.7   root     3563:                 gen_helper_cvttps2pi(cpu_ptr0, cpu_ptr1);
1.1       root     3564:                 break;
                   3565:             case 0x12c:
1.1.1.7   root     3566:                 gen_helper_cvttpd2pi(cpu_ptr0, cpu_ptr1);
1.1       root     3567:                 break;
                   3568:             case 0x02d:
1.1.1.7   root     3569:                 gen_helper_cvtps2pi(cpu_ptr0, cpu_ptr1);
1.1       root     3570:                 break;
                   3571:             case 0x12d:
1.1.1.7   root     3572:                 gen_helper_cvtpd2pi(cpu_ptr0, cpu_ptr1);
1.1       root     3573:                 break;
                   3574:             }
                   3575:             break;
                   3576:         case 0x22c: /* cvttss2si */
                   3577:         case 0x32c: /* cvttsd2si */
                   3578:         case 0x22d: /* cvtss2si */
                   3579:         case 0x32d: /* cvtsd2si */
                   3580:             ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
                   3581:             if (mod != 3) {
                   3582:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3583:                 if ((b >> 8) & 1) {
1.1.1.7   root     3584:                     gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_Q(0)));
1.1       root     3585:                 } else {
1.1.1.7   root     3586:                     gen_op_ld_T0_A0(OT_LONG + s->mem_index);
                   3587:                     tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
1.1       root     3588:                 }
                   3589:                 op2_offset = offsetof(CPUX86State,xmm_t0);
                   3590:             } else {
                   3591:                 rm = (modrm & 7) | REX_B(s);
                   3592:                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
                   3593:             }
1.1.1.7   root     3594:             sse_op2 = sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2) + 4 +
                   3595:                                     (b & 1) * 4];
                   3596:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
                   3597:             if (ot == OT_LONG) {
                   3598:                 ((void (*)(TCGv_i32, TCGv_ptr))sse_op2)(cpu_tmp2_i32, cpu_ptr0);
                   3599:                 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
                   3600:             } else {
                   3601:                 ((void (*)(TCGv, TCGv_ptr))sse_op2)(cpu_T[0], cpu_ptr0);
                   3602:             }
                   3603:             gen_op_mov_reg_T0(ot, reg);
1.1       root     3604:             break;
                   3605:         case 0xc4: /* pinsrw */
1.1.1.6   root     3606:         case 0x1c4:
1.1.1.4   root     3607:             s->rip_offset = 1;
1.1       root     3608:             gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
                   3609:             val = ldub_code(s->pc++);
                   3610:             if (b1) {
                   3611:                 val &= 7;
1.1.1.7   root     3612:                 tcg_gen_st16_tl(cpu_T[0], cpu_env,
                   3613:                                 offsetof(CPUX86State,xmm_regs[reg].XMM_W(val)));
1.1       root     3614:             } else {
                   3615:                 val &= 3;
1.1.1.7   root     3616:                 tcg_gen_st16_tl(cpu_T[0], cpu_env,
                   3617:                                 offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val)));
1.1       root     3618:             }
                   3619:             break;
                   3620:         case 0xc5: /* pextrw */
1.1.1.6   root     3621:         case 0x1c5:
1.1       root     3622:             if (mod != 3)
                   3623:                 goto illegal_op;
1.1.1.7   root     3624:             ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
1.1       root     3625:             val = ldub_code(s->pc++);
                   3626:             if (b1) {
                   3627:                 val &= 7;
                   3628:                 rm = (modrm & 7) | REX_B(s);
1.1.1.7   root     3629:                 tcg_gen_ld16u_tl(cpu_T[0], cpu_env,
                   3630:                                  offsetof(CPUX86State,xmm_regs[rm].XMM_W(val)));
1.1       root     3631:             } else {
                   3632:                 val &= 3;
                   3633:                 rm = (modrm & 7);
1.1.1.7   root     3634:                 tcg_gen_ld16u_tl(cpu_T[0], cpu_env,
                   3635:                                 offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
1.1       root     3636:             }
                   3637:             reg = ((modrm >> 3) & 7) | rex_r;
1.1.1.7   root     3638:             gen_op_mov_reg_T0(ot, reg);
1.1       root     3639:             break;
                   3640:         case 0x1d6: /* movq ea, xmm */
                   3641:             if (mod != 3) {
                   3642:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     3643:                 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
1.1       root     3644:             } else {
                   3645:                 rm = (modrm & 7) | REX_B(s);
                   3646:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
                   3647:                             offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
                   3648:                 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
                   3649:             }
                   3650:             break;
                   3651:         case 0x2d6: /* movq2dq */
1.1.1.7   root     3652:             gen_helper_enter_mmx();
1.1.1.4   root     3653:             rm = (modrm & 7);
                   3654:             gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
                   3655:                         offsetof(CPUX86State,fpregs[rm].mmx));
                   3656:             gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
1.1       root     3657:             break;
                   3658:         case 0x3d6: /* movdq2q */
1.1.1.7   root     3659:             gen_helper_enter_mmx();
1.1.1.4   root     3660:             rm = (modrm & 7) | REX_B(s);
                   3661:             gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
                   3662:                         offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
1.1       root     3663:             break;
                   3664:         case 0xd7: /* pmovmskb */
                   3665:         case 0x1d7:
                   3666:             if (mod != 3)
                   3667:                 goto illegal_op;
                   3668:             if (b1) {
                   3669:                 rm = (modrm & 7) | REX_B(s);
1.1.1.7   root     3670:                 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm]));
                   3671:                 gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_ptr0);
1.1       root     3672:             } else {
                   3673:                 rm = (modrm & 7);
1.1.1.7   root     3674:                 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx));
                   3675:                 gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_ptr0);
                   3676:             }
                   3677:             tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
                   3678:             reg = ((modrm >> 3) & 7) | rex_r;
                   3679:             gen_op_mov_reg_T0(OT_LONG, reg);
                   3680:             break;
                   3681:         case 0x138:
                   3682:             if (s->prefix & PREFIX_REPNZ)
                   3683:                 goto crc32;
                   3684:         case 0x038:
                   3685:             b = modrm;
                   3686:             modrm = ldub_code(s->pc++);
                   3687:             rm = modrm & 7;
                   3688:             reg = ((modrm >> 3) & 7) | rex_r;
                   3689:             mod = (modrm >> 6) & 3;
1.1.1.13  root     3690:             if (b1 >= 2) {
                   3691:                 goto illegal_op;
                   3692:             }
1.1.1.7   root     3693: 
                   3694:             sse_op2 = sse_op_table6[b].op[b1];
                   3695:             if (!sse_op2)
                   3696:                 goto illegal_op;
                   3697:             if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
                   3698:                 goto illegal_op;
                   3699: 
                   3700:             if (b1) {
                   3701:                 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
                   3702:                 if (mod == 3) {
                   3703:                     op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
                   3704:                 } else {
                   3705:                     op2_offset = offsetof(CPUX86State,xmm_t0);
                   3706:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3707:                     switch (b) {
                   3708:                     case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
                   3709:                     case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
                   3710:                     case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
                   3711:                         gen_ldq_env_A0(s->mem_index, op2_offset +
                   3712:                                         offsetof(XMMReg, XMM_Q(0)));
                   3713:                         break;
                   3714:                     case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
                   3715:                     case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
                   3716:                         tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
                   3717:                                           (s->mem_index >> 2) - 1);
                   3718:                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
                   3719:                         tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset +
                   3720:                                         offsetof(XMMReg, XMM_L(0)));
                   3721:                         break;
                   3722:                     case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
                   3723:                         tcg_gen_qemu_ld16u(cpu_tmp0, cpu_A0,
                   3724:                                           (s->mem_index >> 2) - 1);
                   3725:                         tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset +
                   3726:                                         offsetof(XMMReg, XMM_W(0)));
                   3727:                         break;
                   3728:                     case 0x2a:            /* movntqda */
                   3729:                         gen_ldo_env_A0(s->mem_index, op1_offset);
                   3730:                         return;
                   3731:                     default:
                   3732:                         gen_ldo_env_A0(s->mem_index, op2_offset);
                   3733:                     }
                   3734:                 }
                   3735:             } else {
                   3736:                 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
                   3737:                 if (mod == 3) {
                   3738:                     op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
                   3739:                 } else {
                   3740:                     op2_offset = offsetof(CPUX86State,mmx_t0);
                   3741:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3742:                     gen_ldq_env_A0(s->mem_index, op2_offset);
                   3743:                 }
1.1       root     3744:             }
1.1.1.7   root     3745:             if (sse_op2 == SSE_SPECIAL)
                   3746:                 goto illegal_op;
                   3747: 
                   3748:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
                   3749:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
                   3750:             ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
                   3751: 
                   3752:             if (b == 0x17)
                   3753:                 s->cc_op = CC_OP_EFLAGS;
                   3754:             break;
                   3755:         case 0x338: /* crc32 */
                   3756:         crc32:
                   3757:             b = modrm;
                   3758:             modrm = ldub_code(s->pc++);
                   3759:             reg = ((modrm >> 3) & 7) | rex_r;
                   3760: 
                   3761:             if (b != 0xf0 && b != 0xf1)
                   3762:                 goto illegal_op;
                   3763:             if (!(s->cpuid_ext_features & CPUID_EXT_SSE42))
                   3764:                 goto illegal_op;
                   3765: 
                   3766:             if (b == 0xf0)
                   3767:                 ot = OT_BYTE;
                   3768:             else if (b == 0xf1 && s->dflag != 2)
                   3769:                 if (s->prefix & PREFIX_DATA)
                   3770:                     ot = OT_WORD;
                   3771:                 else
                   3772:                     ot = OT_LONG;
                   3773:             else
                   3774:                 ot = OT_QUAD;
                   3775: 
                   3776:             gen_op_mov_TN_reg(OT_LONG, 0, reg);
                   3777:             tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   3778:             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
                   3779:             gen_helper_crc32(cpu_T[0], cpu_tmp2_i32,
                   3780:                              cpu_T[0], tcg_const_i32(8 << ot));
                   3781: 
                   3782:             ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
                   3783:             gen_op_mov_reg_T0(ot, reg);
                   3784:             break;
                   3785:         case 0x03a:
                   3786:         case 0x13a:
                   3787:             b = modrm;
                   3788:             modrm = ldub_code(s->pc++);
                   3789:             rm = modrm & 7;
1.1       root     3790:             reg = ((modrm >> 3) & 7) | rex_r;
1.1.1.7   root     3791:             mod = (modrm >> 6) & 3;
1.1.1.13  root     3792:             if (b1 >= 2) {
                   3793:                 goto illegal_op;
                   3794:             }
1.1.1.7   root     3795: 
                   3796:             sse_op2 = sse_op_table7[b].op[b1];
                   3797:             if (!sse_op2)
                   3798:                 goto illegal_op;
                   3799:             if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
                   3800:                 goto illegal_op;
                   3801: 
                   3802:             if (sse_op2 == SSE_SPECIAL) {
                   3803:                 ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
                   3804:                 rm = (modrm & 7) | REX_B(s);
                   3805:                 if (mod != 3)
                   3806:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3807:                 reg = ((modrm >> 3) & 7) | rex_r;
                   3808:                 val = ldub_code(s->pc++);
                   3809:                 switch (b) {
                   3810:                 case 0x14: /* pextrb */
                   3811:                     tcg_gen_ld8u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
                   3812:                                             xmm_regs[reg].XMM_B(val & 15)));
                   3813:                     if (mod == 3)
                   3814:                         gen_op_mov_reg_T0(ot, rm);
                   3815:                     else
                   3816:                         tcg_gen_qemu_st8(cpu_T[0], cpu_A0,
                   3817:                                         (s->mem_index >> 2) - 1);
                   3818:                     break;
                   3819:                 case 0x15: /* pextrw */
                   3820:                     tcg_gen_ld16u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
                   3821:                                             xmm_regs[reg].XMM_W(val & 7)));
                   3822:                     if (mod == 3)
                   3823:                         gen_op_mov_reg_T0(ot, rm);
                   3824:                     else
                   3825:                         tcg_gen_qemu_st16(cpu_T[0], cpu_A0,
                   3826:                                         (s->mem_index >> 2) - 1);
                   3827:                     break;
                   3828:                 case 0x16:
                   3829:                     if (ot == OT_LONG) { /* pextrd */
                   3830:                         tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
                   3831:                                         offsetof(CPUX86State,
                   3832:                                                 xmm_regs[reg].XMM_L(val & 3)));
                   3833:                         tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
                   3834:                         if (mod == 3)
                   3835:                             gen_op_mov_reg_v(ot, rm, cpu_T[0]);
                   3836:                         else
                   3837:                             tcg_gen_qemu_st32(cpu_T[0], cpu_A0,
                   3838:                                             (s->mem_index >> 2) - 1);
                   3839:                     } else { /* pextrq */
                   3840: #ifdef TARGET_X86_64
                   3841:                         tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
                   3842:                                         offsetof(CPUX86State,
                   3843:                                                 xmm_regs[reg].XMM_Q(val & 1)));
                   3844:                         if (mod == 3)
                   3845:                             gen_op_mov_reg_v(ot, rm, cpu_tmp1_i64);
                   3846:                         else
                   3847:                             tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0,
                   3848:                                             (s->mem_index >> 2) - 1);
                   3849: #else
                   3850:                         goto illegal_op;
                   3851: #endif
                   3852:                     }
                   3853:                     break;
                   3854:                 case 0x17: /* extractps */
                   3855:                     tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
                   3856:                                             xmm_regs[reg].XMM_L(val & 3)));
                   3857:                     if (mod == 3)
                   3858:                         gen_op_mov_reg_T0(ot, rm);
                   3859:                     else
                   3860:                         tcg_gen_qemu_st32(cpu_T[0], cpu_A0,
                   3861:                                         (s->mem_index >> 2) - 1);
                   3862:                     break;
                   3863:                 case 0x20: /* pinsrb */
                   3864:                     if (mod == 3)
                   3865:                         gen_op_mov_TN_reg(OT_LONG, 0, rm);
                   3866:                     else
                   3867:                         tcg_gen_qemu_ld8u(cpu_tmp0, cpu_A0,
                   3868:                                         (s->mem_index >> 2) - 1);
                   3869:                     tcg_gen_st8_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State,
                   3870:                                             xmm_regs[reg].XMM_B(val & 15)));
                   3871:                     break;
                   3872:                 case 0x21: /* insertps */
                   3873:                     if (mod == 3) {
                   3874:                         tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
                   3875:                                         offsetof(CPUX86State,xmm_regs[rm]
                   3876:                                                 .XMM_L((val >> 6) & 3)));
                   3877:                     } else {
                   3878:                         tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
                   3879:                                         (s->mem_index >> 2) - 1);
                   3880:                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
                   3881:                     }
                   3882:                     tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
                   3883:                                     offsetof(CPUX86State,xmm_regs[reg]
                   3884:                                             .XMM_L((val >> 4) & 3)));
                   3885:                     if ((val >> 0) & 1)
                   3886:                         tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
                   3887:                                         cpu_env, offsetof(CPUX86State,
                   3888:                                                 xmm_regs[reg].XMM_L(0)));
                   3889:                     if ((val >> 1) & 1)
                   3890:                         tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
                   3891:                                         cpu_env, offsetof(CPUX86State,
                   3892:                                                 xmm_regs[reg].XMM_L(1)));
                   3893:                     if ((val >> 2) & 1)
                   3894:                         tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
                   3895:                                         cpu_env, offsetof(CPUX86State,
                   3896:                                                 xmm_regs[reg].XMM_L(2)));
                   3897:                     if ((val >> 3) & 1)
                   3898:                         tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
                   3899:                                         cpu_env, offsetof(CPUX86State,
                   3900:                                                 xmm_regs[reg].XMM_L(3)));
                   3901:                     break;
                   3902:                 case 0x22:
                   3903:                     if (ot == OT_LONG) { /* pinsrd */
                   3904:                         if (mod == 3)
                   3905:                             gen_op_mov_v_reg(ot, cpu_tmp0, rm);
                   3906:                         else
                   3907:                             tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
                   3908:                                             (s->mem_index >> 2) - 1);
                   3909:                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
                   3910:                         tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
                   3911:                                         offsetof(CPUX86State,
                   3912:                                                 xmm_regs[reg].XMM_L(val & 3)));
                   3913:                     } else { /* pinsrq */
                   3914: #ifdef TARGET_X86_64
                   3915:                         if (mod == 3)
                   3916:                             gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);
                   3917:                         else
                   3918:                             tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0,
                   3919:                                             (s->mem_index >> 2) - 1);
                   3920:                         tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
                   3921:                                         offsetof(CPUX86State,
                   3922:                                                 xmm_regs[reg].XMM_Q(val & 1)));
                   3923: #else
                   3924:                         goto illegal_op;
                   3925: #endif
                   3926:                     }
                   3927:                     break;
                   3928:                 }
                   3929:                 return;
                   3930:             }
                   3931: 
                   3932:             if (b1) {
                   3933:                 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
                   3934:                 if (mod == 3) {
                   3935:                     op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
                   3936:                 } else {
                   3937:                     op2_offset = offsetof(CPUX86State,xmm_t0);
                   3938:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3939:                     gen_ldo_env_A0(s->mem_index, op2_offset);
                   3940:                 }
                   3941:             } else {
                   3942:                 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
                   3943:                 if (mod == 3) {
                   3944:                     op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
                   3945:                 } else {
                   3946:                     op2_offset = offsetof(CPUX86State,mmx_t0);
                   3947:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3948:                     gen_ldq_env_A0(s->mem_index, op2_offset);
                   3949:                 }
                   3950:             }
                   3951:             val = ldub_code(s->pc++);
                   3952: 
                   3953:             if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
                   3954:                 s->cc_op = CC_OP_EFLAGS;
                   3955: 
                   3956:                 if (s->dflag == 2)
                   3957:                     /* The helper must use entire 64-bit gp registers */
                   3958:                     val |= 1 << 8;
                   3959:             }
                   3960: 
                   3961:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
                   3962:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
                   3963:             ((void (*)(TCGv_ptr, TCGv_ptr, TCGv_i32))sse_op2)(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
1.1       root     3964:             break;
                   3965:         default:
                   3966:             goto illegal_op;
                   3967:         }
                   3968:     } else {
                   3969:         /* generic MMX or SSE operation */
1.1.1.4   root     3970:         switch(b) {
                   3971:         case 0x70: /* pshufx insn */
                   3972:         case 0xc6: /* pshufx insn */
                   3973:         case 0xc2: /* compare insns */
                   3974:             s->rip_offset = 1;
                   3975:             break;
                   3976:         default:
                   3977:             break;
1.1       root     3978:         }
                   3979:         if (is_xmm) {
                   3980:             op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
                   3981:             if (mod != 3) {
                   3982:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3983:                 op2_offset = offsetof(CPUX86State,xmm_t0);
1.1.1.4   root     3984:                 if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f && b != 0x5b) ||
1.1       root     3985:                                 b == 0xc2)) {
                   3986:                     /* specific case for SSE single instructions */
                   3987:                     if (b1 == 2) {
                   3988:                         /* 32 bit access */
1.1.1.7   root     3989:                         gen_op_ld_T0_A0(OT_LONG + s->mem_index);
                   3990:                         tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
1.1       root     3991:                     } else {
                   3992:                         /* 64 bit access */
1.1.1.7   root     3993:                         gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_D(0)));
1.1       root     3994:                     }
                   3995:                 } else {
1.1.1.7   root     3996:                     gen_ldo_env_A0(s->mem_index, op2_offset);
1.1       root     3997:                 }
                   3998:             } else {
                   3999:                 rm = (modrm & 7) | REX_B(s);
                   4000:                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
                   4001:             }
                   4002:         } else {
                   4003:             op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
                   4004:             if (mod != 3) {
                   4005:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   4006:                 op2_offset = offsetof(CPUX86State,mmx_t0);
1.1.1.7   root     4007:                 gen_ldq_env_A0(s->mem_index, op2_offset);
1.1       root     4008:             } else {
                   4009:                 rm = (modrm & 7);
                   4010:                 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
                   4011:             }
                   4012:         }
                   4013:         switch(b) {
1.1.1.7   root     4014:         case 0x0f: /* 3DNow! data insns */
                   4015:             if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
                   4016:                 goto illegal_op;
                   4017:             val = ldub_code(s->pc++);
                   4018:             sse_op2 = sse_op_table5[val];
                   4019:             if (!sse_op2)
                   4020:                 goto illegal_op;
                   4021:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
                   4022:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
                   4023:             ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
                   4024:             break;
1.1       root     4025:         case 0x70: /* pshufx insn */
                   4026:         case 0xc6: /* pshufx insn */
                   4027:             val = ldub_code(s->pc++);
1.1.1.7   root     4028:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
                   4029:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
                   4030:             ((void (*)(TCGv_ptr, TCGv_ptr, TCGv_i32))sse_op2)(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
1.1       root     4031:             break;
                   4032:         case 0xc2:
                   4033:             /* compare insns */
                   4034:             val = ldub_code(s->pc++);
                   4035:             if (val >= 8)
                   4036:                 goto illegal_op;
                   4037:             sse_op2 = sse_op_table4[val][b1];
1.1.1.7   root     4038:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
                   4039:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
                   4040:             ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
                   4041:             break;
                   4042:         case 0xf7:
                   4043:             /* maskmov : we must prepare A0 */
                   4044:             if (mod != 3)
                   4045:                 goto illegal_op;
                   4046: #ifdef TARGET_X86_64
                   4047:             if (s->aflag == 2) {
                   4048:                 gen_op_movq_A0_reg(R_EDI);
                   4049:             } else
                   4050: #endif
                   4051:             {
                   4052:                 gen_op_movl_A0_reg(R_EDI);
                   4053:                 if (s->aflag == 0)
                   4054:                     gen_op_andl_A0_ffff();
                   4055:             }
                   4056:             gen_add_A0_ds_seg(s);
                   4057: 
                   4058:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
                   4059:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
                   4060:             ((void (*)(TCGv_ptr, TCGv_ptr, TCGv))sse_op2)(cpu_ptr0, cpu_ptr1, cpu_A0);
1.1       root     4061:             break;
                   4062:         default:
1.1.1.7   root     4063:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
                   4064:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
                   4065:             ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
1.1       root     4066:             break;
                   4067:         }
                   4068:         if (b == 0x2e || b == 0x2f) {
                   4069:             s->cc_op = CC_OP_EFLAGS;
                   4070:         }
                   4071:     }
                   4072: }
                   4073: 
                   4074: /* convert one instruction. s->is_jmp is set if the translation must
                   4075:    be stopped. Return the next pc value */
                   4076: static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
                   4077: {
                   4078:     int b, prefixes, aflag, dflag;
                   4079:     int shift, ot;
                   4080:     int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
                   4081:     target_ulong next_eip, tval;
                   4082:     int rex_w, rex_r;
                   4083: 
1.1.1.7   root     4084:     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
                   4085:         tcg_gen_debug_insn_start(pc_start);
1.1       root     4086:     s->pc = pc_start;
                   4087:     prefixes = 0;
                   4088:     aflag = s->code32;
                   4089:     dflag = s->code32;
                   4090:     s->override = -1;
                   4091:     rex_w = -1;
                   4092:     rex_r = 0;
                   4093: #ifdef TARGET_X86_64
                   4094:     s->rex_x = 0;
                   4095:     s->rex_b = 0;
1.1.1.6   root     4096:     x86_64_hregs = 0;
1.1       root     4097: #endif
                   4098:     s->rip_offset = 0; /* for relative ip address */
                   4099:  next_byte:
                   4100:     b = ldub_code(s->pc);
                   4101:     s->pc++;
                   4102:     /* check prefixes */
                   4103: #ifdef TARGET_X86_64
                   4104:     if (CODE64(s)) {
                   4105:         switch (b) {
                   4106:         case 0xf3:
                   4107:             prefixes |= PREFIX_REPZ;
                   4108:             goto next_byte;
                   4109:         case 0xf2:
                   4110:             prefixes |= PREFIX_REPNZ;
                   4111:             goto next_byte;
                   4112:         case 0xf0:
                   4113:             prefixes |= PREFIX_LOCK;
                   4114:             goto next_byte;
                   4115:         case 0x2e:
                   4116:             s->override = R_CS;
                   4117:             goto next_byte;
                   4118:         case 0x36:
                   4119:             s->override = R_SS;
                   4120:             goto next_byte;
                   4121:         case 0x3e:
                   4122:             s->override = R_DS;
                   4123:             goto next_byte;
                   4124:         case 0x26:
                   4125:             s->override = R_ES;
                   4126:             goto next_byte;
                   4127:         case 0x64:
                   4128:             s->override = R_FS;
                   4129:             goto next_byte;
                   4130:         case 0x65:
                   4131:             s->override = R_GS;
                   4132:             goto next_byte;
                   4133:         case 0x66:
                   4134:             prefixes |= PREFIX_DATA;
                   4135:             goto next_byte;
                   4136:         case 0x67:
                   4137:             prefixes |= PREFIX_ADR;
                   4138:             goto next_byte;
                   4139:         case 0x40 ... 0x4f:
                   4140:             /* REX prefix */
                   4141:             rex_w = (b >> 3) & 1;
                   4142:             rex_r = (b & 0x4) << 1;
                   4143:             s->rex_x = (b & 0x2) << 2;
                   4144:             REX_B(s) = (b & 0x1) << 3;
                   4145:             x86_64_hregs = 1; /* select uniform byte register addressing */
                   4146:             goto next_byte;
                   4147:         }
                   4148:         if (rex_w == 1) {
                   4149:             /* 0x66 is ignored if rex.w is set */
                   4150:             dflag = 2;
                   4151:         } else {
                   4152:             if (prefixes & PREFIX_DATA)
                   4153:                 dflag ^= 1;
                   4154:         }
                   4155:         if (!(prefixes & PREFIX_ADR))
                   4156:             aflag = 2;
1.1.1.6   root     4157:     } else
1.1       root     4158: #endif
                   4159:     {
                   4160:         switch (b) {
                   4161:         case 0xf3:
                   4162:             prefixes |= PREFIX_REPZ;
                   4163:             goto next_byte;
                   4164:         case 0xf2:
                   4165:             prefixes |= PREFIX_REPNZ;
                   4166:             goto next_byte;
                   4167:         case 0xf0:
                   4168:             prefixes |= PREFIX_LOCK;
                   4169:             goto next_byte;
                   4170:         case 0x2e:
                   4171:             s->override = R_CS;
                   4172:             goto next_byte;
                   4173:         case 0x36:
                   4174:             s->override = R_SS;
                   4175:             goto next_byte;
                   4176:         case 0x3e:
                   4177:             s->override = R_DS;
                   4178:             goto next_byte;
                   4179:         case 0x26:
                   4180:             s->override = R_ES;
                   4181:             goto next_byte;
                   4182:         case 0x64:
                   4183:             s->override = R_FS;
                   4184:             goto next_byte;
                   4185:         case 0x65:
                   4186:             s->override = R_GS;
                   4187:             goto next_byte;
                   4188:         case 0x66:
                   4189:             prefixes |= PREFIX_DATA;
                   4190:             goto next_byte;
                   4191:         case 0x67:
                   4192:             prefixes |= PREFIX_ADR;
                   4193:             goto next_byte;
                   4194:         }
                   4195:         if (prefixes & PREFIX_DATA)
                   4196:             dflag ^= 1;
                   4197:         if (prefixes & PREFIX_ADR)
                   4198:             aflag ^= 1;
                   4199:     }
                   4200: 
                   4201:     s->prefix = prefixes;
                   4202:     s->aflag = aflag;
                   4203:     s->dflag = dflag;
                   4204: 
                   4205:     /* lock generation */
                   4206:     if (prefixes & PREFIX_LOCK)
1.1.1.7   root     4207:         gen_helper_lock();
1.1       root     4208: 
                   4209:     /* now check op code */
                   4210:  reswitch:
                   4211:     switch(b) {
                   4212:     case 0x0f:
                   4213:         /**************************/
                   4214:         /* extended op code */
                   4215:         b = ldub_code(s->pc++) | 0x100;
                   4216:         goto reswitch;
1.1.1.6   root     4217: 
1.1       root     4218:         /**************************/
                   4219:         /* arith & logic */
                   4220:     case 0x00 ... 0x05:
                   4221:     case 0x08 ... 0x0d:
                   4222:     case 0x10 ... 0x15:
                   4223:     case 0x18 ... 0x1d:
                   4224:     case 0x20 ... 0x25:
                   4225:     case 0x28 ... 0x2d:
                   4226:     case 0x30 ... 0x35:
                   4227:     case 0x38 ... 0x3d:
                   4228:         {
                   4229:             int op, f, val;
                   4230:             op = (b >> 3) & 7;
                   4231:             f = (b >> 1) & 3;
                   4232: 
                   4233:             if ((b & 1) == 0)
                   4234:                 ot = OT_BYTE;
                   4235:             else
                   4236:                 ot = dflag + OT_WORD;
1.1.1.6   root     4237: 
1.1       root     4238:             switch(f) {
                   4239:             case 0: /* OP Ev, Gv */
                   4240:                 modrm = ldub_code(s->pc++);
                   4241:                 reg = ((modrm >> 3) & 7) | rex_r;
                   4242:                 mod = (modrm >> 6) & 3;
                   4243:                 rm = (modrm & 7) | REX_B(s);
                   4244:                 if (mod != 3) {
                   4245:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   4246:                     opreg = OR_TMP0;
                   4247:                 } else if (op == OP_XORL && rm == reg) {
                   4248:                 xor_zero:
                   4249:                     /* xor reg, reg optimisation */
                   4250:                     gen_op_movl_T0_0();
                   4251:                     s->cc_op = CC_OP_LOGICB + ot;
1.1.1.7   root     4252:                     gen_op_mov_reg_T0(ot, reg);
1.1       root     4253:                     gen_op_update1_cc();
                   4254:                     break;
                   4255:                 } else {
                   4256:                     opreg = rm;
                   4257:                 }
1.1.1.7   root     4258:                 gen_op_mov_TN_reg(ot, 1, reg);
1.1       root     4259:                 gen_op(s, op, ot, opreg);
                   4260:                 break;
                   4261:             case 1: /* OP Gv, Ev */
                   4262:                 modrm = ldub_code(s->pc++);
                   4263:                 mod = (modrm >> 6) & 3;
                   4264:                 reg = ((modrm >> 3) & 7) | rex_r;
                   4265:                 rm = (modrm & 7) | REX_B(s);
                   4266:                 if (mod != 3) {
                   4267:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     4268:                     gen_op_ld_T1_A0(ot + s->mem_index);
1.1       root     4269:                 } else if (op == OP_XORL && rm == reg) {
                   4270:                     goto xor_zero;
                   4271:                 } else {
1.1.1.7   root     4272:                     gen_op_mov_TN_reg(ot, 1, rm);
1.1       root     4273:                 }
                   4274:                 gen_op(s, op, ot, reg);
                   4275:                 break;
                   4276:             case 2: /* OP A, Iv */
                   4277:                 val = insn_get(s, ot);
                   4278:                 gen_op_movl_T1_im(val);
                   4279:                 gen_op(s, op, ot, OR_EAX);
                   4280:                 break;
                   4281:             }
                   4282:         }
                   4283:         break;
                   4284: 
1.1.1.7   root     4285:     case 0x82:
                   4286:         if (CODE64(s))
                   4287:             goto illegal_op;
1.1       root     4288:     case 0x80: /* GRP1 */
                   4289:     case 0x81:
                   4290:     case 0x83:
                   4291:         {
                   4292:             int val;
                   4293: 
                   4294:             if ((b & 1) == 0)
                   4295:                 ot = OT_BYTE;
                   4296:             else
                   4297:                 ot = dflag + OT_WORD;
1.1.1.6   root     4298: 
1.1       root     4299:             modrm = ldub_code(s->pc++);
                   4300:             mod = (modrm >> 6) & 3;
                   4301:             rm = (modrm & 7) | REX_B(s);
                   4302:             op = (modrm >> 3) & 7;
1.1.1.6   root     4303: 
1.1       root     4304:             if (mod != 3) {
                   4305:                 if (b == 0x83)
                   4306:                     s->rip_offset = 1;
                   4307:                 else
                   4308:                     s->rip_offset = insn_const_size(ot);
                   4309:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   4310:                 opreg = OR_TMP0;
                   4311:             } else {
                   4312:                 opreg = rm;
                   4313:             }
                   4314: 
                   4315:             switch(b) {
                   4316:             default:
                   4317:             case 0x80:
                   4318:             case 0x81:
                   4319:             case 0x82:
                   4320:                 val = insn_get(s, ot);
                   4321:                 break;
                   4322:             case 0x83:
                   4323:                 val = (int8_t)insn_get(s, OT_BYTE);
                   4324:                 break;
                   4325:             }
                   4326:             gen_op_movl_T1_im(val);
                   4327:             gen_op(s, op, ot, opreg);
                   4328:         }
                   4329:         break;
                   4330: 
                   4331:         /**************************/
                   4332:         /* inc, dec, and other misc arith */
                   4333:     case 0x40 ... 0x47: /* inc Gv */
                   4334:         ot = dflag ? OT_LONG : OT_WORD;
                   4335:         gen_inc(s, ot, OR_EAX + (b & 7), 1);
                   4336:         break;
                   4337:     case 0x48 ... 0x4f: /* dec Gv */
                   4338:         ot = dflag ? OT_LONG : OT_WORD;
                   4339:         gen_inc(s, ot, OR_EAX + (b & 7), -1);
                   4340:         break;
                   4341:     case 0xf6: /* GRP3 */
                   4342:     case 0xf7:
                   4343:         if ((b & 1) == 0)
                   4344:             ot = OT_BYTE;
                   4345:         else
                   4346:             ot = dflag + OT_WORD;
                   4347: 
                   4348:         modrm = ldub_code(s->pc++);
                   4349:         mod = (modrm >> 6) & 3;
                   4350:         rm = (modrm & 7) | REX_B(s);
                   4351:         op = (modrm >> 3) & 7;
                   4352:         if (mod != 3) {
                   4353:             if (op == 0)
                   4354:                 s->rip_offset = insn_const_size(ot);
                   4355:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     4356:             gen_op_ld_T0_A0(ot + s->mem_index);
1.1       root     4357:         } else {
1.1.1.7   root     4358:             gen_op_mov_TN_reg(ot, 0, rm);
1.1       root     4359:         }
                   4360: 
                   4361:         switch(op) {
                   4362:         case 0: /* test */
                   4363:             val = insn_get(s, ot);
                   4364:             gen_op_movl_T1_im(val);
                   4365:             gen_op_testl_T0_T1_cc();
                   4366:             s->cc_op = CC_OP_LOGICB + ot;
                   4367:             break;
                   4368:         case 2: /* not */
1.1.1.7   root     4369:             tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
1.1       root     4370:             if (mod != 3) {
1.1.1.7   root     4371:                 gen_op_st_T0_A0(ot + s->mem_index);
1.1       root     4372:             } else {
1.1.1.7   root     4373:                 gen_op_mov_reg_T0(ot, rm);
1.1       root     4374:             }
                   4375:             break;
                   4376:         case 3: /* neg */
1.1.1.7   root     4377:             tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
1.1       root     4378:             if (mod != 3) {
1.1.1.7   root     4379:                 gen_op_st_T0_A0(ot + s->mem_index);
1.1       root     4380:             } else {
1.1.1.7   root     4381:                 gen_op_mov_reg_T0(ot, rm);
1.1       root     4382:             }
                   4383:             gen_op_update_neg_cc();
                   4384:             s->cc_op = CC_OP_SUBB + ot;
                   4385:             break;
                   4386:         case 4: /* mul */
                   4387:             switch(ot) {
                   4388:             case OT_BYTE:
1.1.1.7   root     4389:                 gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX);
                   4390:                 tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
                   4391:                 tcg_gen_ext8u_tl(cpu_T[1], cpu_T[1]);
                   4392:                 /* XXX: use 32 bit mul which could be faster */
                   4393:                 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
                   4394:                 gen_op_mov_reg_T0(OT_WORD, R_EAX);
                   4395:                 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
                   4396:                 tcg_gen_andi_tl(cpu_cc_src, cpu_T[0], 0xff00);
1.1       root     4397:                 s->cc_op = CC_OP_MULB;
                   4398:                 break;
                   4399:             case OT_WORD:
1.1.1.7   root     4400:                 gen_op_mov_TN_reg(OT_WORD, 1, R_EAX);
                   4401:                 tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
                   4402:                 tcg_gen_ext16u_tl(cpu_T[1], cpu_T[1]);
                   4403:                 /* XXX: use 32 bit mul which could be faster */
                   4404:                 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
                   4405:                 gen_op_mov_reg_T0(OT_WORD, R_EAX);
                   4406:                 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
                   4407:                 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
                   4408:                 gen_op_mov_reg_T0(OT_WORD, R_EDX);
                   4409:                 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
1.1       root     4410:                 s->cc_op = CC_OP_MULW;
                   4411:                 break;
                   4412:             default:
                   4413:             case OT_LONG:
1.1.1.7   root     4414: #ifdef TARGET_X86_64
                   4415:                 gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
                   4416:                 tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
                   4417:                 tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
                   4418:                 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
                   4419:                 gen_op_mov_reg_T0(OT_LONG, R_EAX);
                   4420:                 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
                   4421:                 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
                   4422:                 gen_op_mov_reg_T0(OT_LONG, R_EDX);
                   4423:                 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
                   4424: #else
                   4425:                 {
                   4426:                     TCGv_i64 t0, t1;
                   4427:                     t0 = tcg_temp_new_i64();
                   4428:                     t1 = tcg_temp_new_i64();
                   4429:                     gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
                   4430:                     tcg_gen_extu_i32_i64(t0, cpu_T[0]);
                   4431:                     tcg_gen_extu_i32_i64(t1, cpu_T[1]);
                   4432:                     tcg_gen_mul_i64(t0, t0, t1);
                   4433:                     tcg_gen_trunc_i64_i32(cpu_T[0], t0);
                   4434:                     gen_op_mov_reg_T0(OT_LONG, R_EAX);
                   4435:                     tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
                   4436:                     tcg_gen_shri_i64(t0, t0, 32);
                   4437:                     tcg_gen_trunc_i64_i32(cpu_T[0], t0);
                   4438:                     gen_op_mov_reg_T0(OT_LONG, R_EDX);
                   4439:                     tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
                   4440:                 }
                   4441: #endif
1.1       root     4442:                 s->cc_op = CC_OP_MULL;
                   4443:                 break;
                   4444: #ifdef TARGET_X86_64
                   4445:             case OT_QUAD:
1.1.1.7   root     4446:                 gen_helper_mulq_EAX_T0(cpu_T[0]);
1.1       root     4447:                 s->cc_op = CC_OP_MULQ;
                   4448:                 break;
                   4449: #endif
                   4450:             }
                   4451:             break;
                   4452:         case 5: /* imul */
                   4453:             switch(ot) {
                   4454:             case OT_BYTE:
1.1.1.7   root     4455:                 gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX);
                   4456:                 tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
                   4457:                 tcg_gen_ext8s_tl(cpu_T[1], cpu_T[1]);
                   4458:                 /* XXX: use 32 bit mul which could be faster */
                   4459:                 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
                   4460:                 gen_op_mov_reg_T0(OT_WORD, R_EAX);
                   4461:                 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
                   4462:                 tcg_gen_ext8s_tl(cpu_tmp0, cpu_T[0]);
                   4463:                 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
1.1       root     4464:                 s->cc_op = CC_OP_MULB;
                   4465:                 break;
                   4466:             case OT_WORD:
1.1.1.7   root     4467:                 gen_op_mov_TN_reg(OT_WORD, 1, R_EAX);
                   4468:                 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
                   4469:                 tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
                   4470:                 /* XXX: use 32 bit mul which could be faster */
                   4471:                 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
                   4472:                 gen_op_mov_reg_T0(OT_WORD, R_EAX);
                   4473:                 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
                   4474:                 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
                   4475:                 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
                   4476:                 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
                   4477:                 gen_op_mov_reg_T0(OT_WORD, R_EDX);
1.1       root     4478:                 s->cc_op = CC_OP_MULW;
                   4479:                 break;
                   4480:             default:
                   4481:             case OT_LONG:
1.1.1.7   root     4482: #ifdef TARGET_X86_64
                   4483:                 gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
                   4484:                 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
                   4485:                 tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
                   4486:                 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
                   4487:                 gen_op_mov_reg_T0(OT_LONG, R_EAX);
                   4488:                 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
                   4489:                 tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
                   4490:                 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
                   4491:                 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
                   4492:                 gen_op_mov_reg_T0(OT_LONG, R_EDX);
                   4493: #else
                   4494:                 {
                   4495:                     TCGv_i64 t0, t1;
                   4496:                     t0 = tcg_temp_new_i64();
                   4497:                     t1 = tcg_temp_new_i64();
                   4498:                     gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
                   4499:                     tcg_gen_ext_i32_i64(t0, cpu_T[0]);
                   4500:                     tcg_gen_ext_i32_i64(t1, cpu_T[1]);
                   4501:                     tcg_gen_mul_i64(t0, t0, t1);
                   4502:                     tcg_gen_trunc_i64_i32(cpu_T[0], t0);
                   4503:                     gen_op_mov_reg_T0(OT_LONG, R_EAX);
                   4504:                     tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
                   4505:                     tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
                   4506:                     tcg_gen_shri_i64(t0, t0, 32);
                   4507:                     tcg_gen_trunc_i64_i32(cpu_T[0], t0);
                   4508:                     gen_op_mov_reg_T0(OT_LONG, R_EDX);
                   4509:                     tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
                   4510:                 }
                   4511: #endif
1.1       root     4512:                 s->cc_op = CC_OP_MULL;
                   4513:                 break;
                   4514: #ifdef TARGET_X86_64
                   4515:             case OT_QUAD:
1.1.1.7   root     4516:                 gen_helper_imulq_EAX_T0(cpu_T[0]);
1.1       root     4517:                 s->cc_op = CC_OP_MULQ;
                   4518:                 break;
                   4519: #endif
                   4520:             }
                   4521:             break;
                   4522:         case 6: /* div */
                   4523:             switch(ot) {
                   4524:             case OT_BYTE:
                   4525:                 gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     4526:                 gen_helper_divb_AL(cpu_T[0]);
1.1       root     4527:                 break;
                   4528:             case OT_WORD:
                   4529:                 gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     4530:                 gen_helper_divw_AX(cpu_T[0]);
1.1       root     4531:                 break;
                   4532:             default:
                   4533:             case OT_LONG:
                   4534:                 gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     4535:                 gen_helper_divl_EAX(cpu_T[0]);
1.1       root     4536:                 break;
                   4537: #ifdef TARGET_X86_64
                   4538:             case OT_QUAD:
                   4539:                 gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     4540:                 gen_helper_divq_EAX(cpu_T[0]);
1.1       root     4541:                 break;
                   4542: #endif
                   4543:             }
                   4544:             break;
                   4545:         case 7: /* idiv */
                   4546:             switch(ot) {
                   4547:             case OT_BYTE:
                   4548:                 gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     4549:                 gen_helper_idivb_AL(cpu_T[0]);
1.1       root     4550:                 break;
                   4551:             case OT_WORD:
                   4552:                 gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     4553:                 gen_helper_idivw_AX(cpu_T[0]);
1.1       root     4554:                 break;
                   4555:             default:
                   4556:             case OT_LONG:
                   4557:                 gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     4558:                 gen_helper_idivl_EAX(cpu_T[0]);
1.1       root     4559:                 break;
                   4560: #ifdef TARGET_X86_64
                   4561:             case OT_QUAD:
                   4562:                 gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     4563:                 gen_helper_idivq_EAX(cpu_T[0]);
1.1       root     4564:                 break;
                   4565: #endif
                   4566:             }
                   4567:             break;
                   4568:         default:
                   4569:             goto illegal_op;
                   4570:         }
                   4571:         break;
                   4572: 
                   4573:     case 0xfe: /* GRP4 */
                   4574:     case 0xff: /* GRP5 */
                   4575:         if ((b & 1) == 0)
                   4576:             ot = OT_BYTE;
                   4577:         else
                   4578:             ot = dflag + OT_WORD;
                   4579: 
                   4580:         modrm = ldub_code(s->pc++);
                   4581:         mod = (modrm >> 6) & 3;
                   4582:         rm = (modrm & 7) | REX_B(s);
                   4583:         op = (modrm >> 3) & 7;
                   4584:         if (op >= 2 && b == 0xfe) {
                   4585:             goto illegal_op;
                   4586:         }
                   4587:         if (CODE64(s)) {
                   4588:             if (op == 2 || op == 4) {
                   4589:                 /* operand size for jumps is 64 bit */
                   4590:                 ot = OT_QUAD;
                   4591:             } else if (op == 3 || op == 5) {
1.1.1.11  root     4592:                 ot = dflag ? OT_LONG + (rex_w == 1) : OT_WORD;
1.1       root     4593:             } else if (op == 6) {
                   4594:                 /* default push size is 64 bit */
                   4595:                 ot = dflag ? OT_QUAD : OT_WORD;
                   4596:             }
                   4597:         }
                   4598:         if (mod != 3) {
                   4599:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   4600:             if (op >= 2 && op != 3 && op != 5)
1.1.1.7   root     4601:                 gen_op_ld_T0_A0(ot + s->mem_index);
1.1       root     4602:         } else {
1.1.1.7   root     4603:             gen_op_mov_TN_reg(ot, 0, rm);
1.1       root     4604:         }
                   4605: 
                   4606:         switch(op) {
                   4607:         case 0: /* inc Ev */
                   4608:             if (mod != 3)
                   4609:                 opreg = OR_TMP0;
                   4610:             else
                   4611:                 opreg = rm;
                   4612:             gen_inc(s, ot, opreg, 1);
                   4613:             break;
                   4614:         case 1: /* dec Ev */
                   4615:             if (mod != 3)
                   4616:                 opreg = OR_TMP0;
                   4617:             else
                   4618:                 opreg = rm;
                   4619:             gen_inc(s, ot, opreg, -1);
                   4620:             break;
                   4621:         case 2: /* call Ev */
                   4622:             /* XXX: optimize if memory (no 'and' is necessary) */
                   4623:             if (s->dflag == 0)
                   4624:                 gen_op_andl_T0_ffff();
                   4625:             next_eip = s->pc - s->cs_base;
                   4626:             gen_movtl_T1_im(next_eip);
                   4627:             gen_push_T1(s);
                   4628:             gen_op_jmp_T0();
                   4629:             gen_eob(s);
                   4630:             break;
                   4631:         case 3: /* lcall Ev */
1.1.1.7   root     4632:             gen_op_ld_T1_A0(ot + s->mem_index);
1.1       root     4633:             gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
1.1.1.7   root     4634:             gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
1.1       root     4635:         do_lcall:
                   4636:             if (s->pe && !s->vm86) {
                   4637:                 if (s->cc_op != CC_OP_DYNAMIC)
                   4638:                     gen_op_set_cc_op(s->cc_op);
                   4639:                 gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     4640:                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   4641:                 gen_helper_lcall_protected(cpu_tmp2_i32, cpu_T[1],
                   4642:                                            tcg_const_i32(dflag), 
                   4643:                                            tcg_const_i32(s->pc - pc_start));
                   4644:             } else {
                   4645:                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   4646:                 gen_helper_lcall_real(cpu_tmp2_i32, cpu_T[1],
                   4647:                                       tcg_const_i32(dflag), 
                   4648:                                       tcg_const_i32(s->pc - s->cs_base));
1.1       root     4649:             }
                   4650:             gen_eob(s);
                   4651:             break;
                   4652:         case 4: /* jmp Ev */
                   4653:             if (s->dflag == 0)
                   4654:                 gen_op_andl_T0_ffff();
                   4655:             gen_op_jmp_T0();
                   4656:             gen_eob(s);
                   4657:             break;
                   4658:         case 5: /* ljmp Ev */
1.1.1.7   root     4659:             gen_op_ld_T1_A0(ot + s->mem_index);
1.1       root     4660:             gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
1.1.1.7   root     4661:             gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
1.1       root     4662:         do_ljmp:
                   4663:             if (s->pe && !s->vm86) {
                   4664:                 if (s->cc_op != CC_OP_DYNAMIC)
                   4665:                     gen_op_set_cc_op(s->cc_op);
                   4666:                 gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     4667:                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   4668:                 gen_helper_ljmp_protected(cpu_tmp2_i32, cpu_T[1],
                   4669:                                           tcg_const_i32(s->pc - pc_start));
1.1       root     4670:             } else {
1.1.1.7   root     4671:                 gen_op_movl_seg_T0_vm(R_CS);
1.1       root     4672:                 gen_op_movl_T0_T1();
                   4673:                 gen_op_jmp_T0();
                   4674:             }
                   4675:             gen_eob(s);
                   4676:             break;
                   4677:         case 6: /* push Ev */
                   4678:             gen_push_T0(s);
                   4679:             break;
                   4680:         default:
                   4681:             goto illegal_op;
                   4682:         }
                   4683:         break;
                   4684: 
                   4685:     case 0x84: /* test Ev, Gv */
1.1.1.6   root     4686:     case 0x85:
1.1       root     4687:         if ((b & 1) == 0)
                   4688:             ot = OT_BYTE;
                   4689:         else
                   4690:             ot = dflag + OT_WORD;
                   4691: 
                   4692:         modrm = ldub_code(s->pc++);
                   4693:         reg = ((modrm >> 3) & 7) | rex_r;
1.1.1.6   root     4694: 
1.1       root     4695:         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1.1.1.7   root     4696:         gen_op_mov_TN_reg(ot, 1, reg);
1.1       root     4697:         gen_op_testl_T0_T1_cc();
                   4698:         s->cc_op = CC_OP_LOGICB + ot;
                   4699:         break;
1.1.1.6   root     4700: 
1.1       root     4701:     case 0xa8: /* test eAX, Iv */
                   4702:     case 0xa9:
                   4703:         if ((b & 1) == 0)
                   4704:             ot = OT_BYTE;
                   4705:         else
                   4706:             ot = dflag + OT_WORD;
                   4707:         val = insn_get(s, ot);
                   4708: 
1.1.1.7   root     4709:         gen_op_mov_TN_reg(ot, 0, OR_EAX);
1.1       root     4710:         gen_op_movl_T1_im(val);
                   4711:         gen_op_testl_T0_T1_cc();
                   4712:         s->cc_op = CC_OP_LOGICB + ot;
                   4713:         break;
1.1.1.6   root     4714: 
1.1       root     4715:     case 0x98: /* CWDE/CBW */
                   4716: #ifdef TARGET_X86_64
                   4717:         if (dflag == 2) {
1.1.1.7   root     4718:             gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
                   4719:             tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
                   4720:             gen_op_mov_reg_T0(OT_QUAD, R_EAX);
1.1       root     4721:         } else
                   4722: #endif
1.1.1.7   root     4723:         if (dflag == 1) {
                   4724:             gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
                   4725:             tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
                   4726:             gen_op_mov_reg_T0(OT_LONG, R_EAX);
                   4727:         } else {
                   4728:             gen_op_mov_TN_reg(OT_BYTE, 0, R_EAX);
                   4729:             tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
                   4730:             gen_op_mov_reg_T0(OT_WORD, R_EAX);
                   4731:         }
1.1       root     4732:         break;
                   4733:     case 0x99: /* CDQ/CWD */
                   4734: #ifdef TARGET_X86_64
                   4735:         if (dflag == 2) {
1.1.1.7   root     4736:             gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
                   4737:             tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 63);
                   4738:             gen_op_mov_reg_T0(OT_QUAD, R_EDX);
1.1       root     4739:         } else
                   4740: #endif
1.1.1.7   root     4741:         if (dflag == 1) {
                   4742:             gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
                   4743:             tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
                   4744:             tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 31);
                   4745:             gen_op_mov_reg_T0(OT_LONG, R_EDX);
                   4746:         } else {
                   4747:             gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
                   4748:             tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
                   4749:             tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 15);
                   4750:             gen_op_mov_reg_T0(OT_WORD, R_EDX);
                   4751:         }
1.1       root     4752:         break;
                   4753:     case 0x1af: /* imul Gv, Ev */
                   4754:     case 0x69: /* imul Gv, Ev, I */
                   4755:     case 0x6b:
                   4756:         ot = dflag + OT_WORD;
                   4757:         modrm = ldub_code(s->pc++);
                   4758:         reg = ((modrm >> 3) & 7) | rex_r;
                   4759:         if (b == 0x69)
                   4760:             s->rip_offset = insn_const_size(ot);
                   4761:         else if (b == 0x6b)
                   4762:             s->rip_offset = 1;
                   4763:         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
                   4764:         if (b == 0x69) {
                   4765:             val = insn_get(s, ot);
                   4766:             gen_op_movl_T1_im(val);
                   4767:         } else if (b == 0x6b) {
                   4768:             val = (int8_t)insn_get(s, OT_BYTE);
                   4769:             gen_op_movl_T1_im(val);
                   4770:         } else {
1.1.1.7   root     4771:             gen_op_mov_TN_reg(ot, 1, reg);
1.1       root     4772:         }
                   4773: 
                   4774: #ifdef TARGET_X86_64
                   4775:         if (ot == OT_QUAD) {
1.1.1.7   root     4776:             gen_helper_imulq_T0_T1(cpu_T[0], cpu_T[0], cpu_T[1]);
1.1       root     4777:         } else
                   4778: #endif
                   4779:         if (ot == OT_LONG) {
1.1.1.7   root     4780: #ifdef TARGET_X86_64
                   4781:                 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
                   4782:                 tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
                   4783:                 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
                   4784:                 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
                   4785:                 tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
                   4786:                 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
                   4787: #else
                   4788:                 {
                   4789:                     TCGv_i64 t0, t1;
                   4790:                     t0 = tcg_temp_new_i64();
                   4791:                     t1 = tcg_temp_new_i64();
                   4792:                     tcg_gen_ext_i32_i64(t0, cpu_T[0]);
                   4793:                     tcg_gen_ext_i32_i64(t1, cpu_T[1]);
                   4794:                     tcg_gen_mul_i64(t0, t0, t1);
                   4795:                     tcg_gen_trunc_i64_i32(cpu_T[0], t0);
                   4796:                     tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
                   4797:                     tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
                   4798:                     tcg_gen_shri_i64(t0, t0, 32);
                   4799:                     tcg_gen_trunc_i64_i32(cpu_T[1], t0);
                   4800:                     tcg_gen_sub_tl(cpu_cc_src, cpu_T[1], cpu_tmp0);
                   4801:                 }
                   4802: #endif
1.1       root     4803:         } else {
1.1.1.7   root     4804:             tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
                   4805:             tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
                   4806:             /* XXX: use 32 bit mul which could be faster */
                   4807:             tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
                   4808:             tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
                   4809:             tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
                   4810:             tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
1.1       root     4811:         }
1.1.1.7   root     4812:         gen_op_mov_reg_T0(ot, reg);
1.1       root     4813:         s->cc_op = CC_OP_MULB + ot;
                   4814:         break;
                   4815:     case 0x1c0:
                   4816:     case 0x1c1: /* xadd Ev, Gv */
                   4817:         if ((b & 1) == 0)
                   4818:             ot = OT_BYTE;
                   4819:         else
                   4820:             ot = dflag + OT_WORD;
                   4821:         modrm = ldub_code(s->pc++);
                   4822:         reg = ((modrm >> 3) & 7) | rex_r;
                   4823:         mod = (modrm >> 6) & 3;
                   4824:         if (mod == 3) {
                   4825:             rm = (modrm & 7) | REX_B(s);
1.1.1.7   root     4826:             gen_op_mov_TN_reg(ot, 0, reg);
                   4827:             gen_op_mov_TN_reg(ot, 1, rm);
1.1       root     4828:             gen_op_addl_T0_T1();
1.1.1.7   root     4829:             gen_op_mov_reg_T1(ot, reg);
                   4830:             gen_op_mov_reg_T0(ot, rm);
1.1       root     4831:         } else {
                   4832:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     4833:             gen_op_mov_TN_reg(ot, 0, reg);
                   4834:             gen_op_ld_T1_A0(ot + s->mem_index);
1.1       root     4835:             gen_op_addl_T0_T1();
1.1.1.7   root     4836:             gen_op_st_T0_A0(ot + s->mem_index);
                   4837:             gen_op_mov_reg_T1(ot, reg);
1.1       root     4838:         }
                   4839:         gen_op_update2_cc();
                   4840:         s->cc_op = CC_OP_ADDB + ot;
                   4841:         break;
                   4842:     case 0x1b0:
                   4843:     case 0x1b1: /* cmpxchg Ev, Gv */
1.1.1.7   root     4844:         {
                   4845:             int label1, label2;
                   4846:             TCGv t0, t1, t2, a0;
                   4847: 
                   4848:             if ((b & 1) == 0)
                   4849:                 ot = OT_BYTE;
                   4850:             else
                   4851:                 ot = dflag + OT_WORD;
                   4852:             modrm = ldub_code(s->pc++);
                   4853:             reg = ((modrm >> 3) & 7) | rex_r;
                   4854:             mod = (modrm >> 6) & 3;
                   4855:             t0 = tcg_temp_local_new();
                   4856:             t1 = tcg_temp_local_new();
                   4857:             t2 = tcg_temp_local_new();
                   4858:             a0 = tcg_temp_local_new();
                   4859:             gen_op_mov_v_reg(ot, t1, reg);
                   4860:             if (mod == 3) {
                   4861:                 rm = (modrm & 7) | REX_B(s);
                   4862:                 gen_op_mov_v_reg(ot, t0, rm);
                   4863:             } else {
                   4864:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   4865:                 tcg_gen_mov_tl(a0, cpu_A0);
                   4866:                 gen_op_ld_v(ot + s->mem_index, t0, a0);
                   4867:                 rm = 0; /* avoid warning */
                   4868:             }
                   4869:             label1 = gen_new_label();
1.1.1.9   root     4870:             tcg_gen_sub_tl(t2, cpu_regs[R_EAX], t0);
1.1.1.7   root     4871:             gen_extu(ot, t2);
                   4872:             tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
1.1.1.16! root     4873:             label2 = gen_new_label();
1.1.1.7   root     4874:             if (mod == 3) {
                   4875:                 gen_op_mov_reg_v(ot, R_EAX, t0);
                   4876:                 tcg_gen_br(label2);
                   4877:                 gen_set_label(label1);
                   4878:                 gen_op_mov_reg_v(ot, rm, t1);
                   4879:             } else {
1.1.1.16! root     4880:                 /* perform no-op store cycle like physical cpu; must be
        !          4881:                    before changing accumulator to ensure idempotency if
        !          4882:                    the store faults and the instruction is restarted */
        !          4883:                 gen_op_st_v(ot + s->mem_index, t0, a0);
1.1.1.7   root     4884:                 gen_op_mov_reg_v(ot, R_EAX, t0);
1.1.1.16! root     4885:                 tcg_gen_br(label2);
1.1.1.7   root     4886:                 gen_set_label(label1);
                   4887:                 gen_op_st_v(ot + s->mem_index, t1, a0);
                   4888:             }
1.1.1.16! root     4889:             gen_set_label(label2);
1.1.1.7   root     4890:             tcg_gen_mov_tl(cpu_cc_src, t0);
                   4891:             tcg_gen_mov_tl(cpu_cc_dst, t2);
                   4892:             s->cc_op = CC_OP_SUBB + ot;
                   4893:             tcg_temp_free(t0);
                   4894:             tcg_temp_free(t1);
                   4895:             tcg_temp_free(t2);
                   4896:             tcg_temp_free(a0);
1.1       root     4897:         }
                   4898:         break;
                   4899:     case 0x1c7: /* cmpxchg8b */
                   4900:         modrm = ldub_code(s->pc++);
                   4901:         mod = (modrm >> 6) & 3;
1.1.1.6   root     4902:         if ((mod == 3) || ((modrm & 0x38) != 0x8))
1.1       root     4903:             goto illegal_op;
1.1.1.7   root     4904: #ifdef TARGET_X86_64
                   4905:         if (dflag == 2) {
                   4906:             if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
                   4907:                 goto illegal_op;
                   4908:             gen_jmp_im(pc_start - s->cs_base);
                   4909:             if (s->cc_op != CC_OP_DYNAMIC)
                   4910:                 gen_op_set_cc_op(s->cc_op);
                   4911:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   4912:             gen_helper_cmpxchg16b(cpu_A0);
                   4913:         } else
                   4914: #endif        
                   4915:         {
                   4916:             if (!(s->cpuid_features & CPUID_CX8))
                   4917:                 goto illegal_op;
                   4918:             gen_jmp_im(pc_start - s->cs_base);
                   4919:             if (s->cc_op != CC_OP_DYNAMIC)
                   4920:                 gen_op_set_cc_op(s->cc_op);
                   4921:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   4922:             gen_helper_cmpxchg8b(cpu_A0);
                   4923:         }
1.1       root     4924:         s->cc_op = CC_OP_EFLAGS;
                   4925:         break;
1.1.1.6   root     4926: 
1.1       root     4927:         /**************************/
                   4928:         /* push/pop */
                   4929:     case 0x50 ... 0x57: /* push */
1.1.1.7   root     4930:         gen_op_mov_TN_reg(OT_LONG, 0, (b & 7) | REX_B(s));
1.1       root     4931:         gen_push_T0(s);
                   4932:         break;
                   4933:     case 0x58 ... 0x5f: /* pop */
                   4934:         if (CODE64(s)) {
                   4935:             ot = dflag ? OT_QUAD : OT_WORD;
                   4936:         } else {
                   4937:             ot = dflag + OT_WORD;
                   4938:         }
                   4939:         gen_pop_T0(s);
                   4940:         /* NOTE: order is important for pop %sp */
                   4941:         gen_pop_update(s);
1.1.1.7   root     4942:         gen_op_mov_reg_T0(ot, (b & 7) | REX_B(s));
1.1       root     4943:         break;
                   4944:     case 0x60: /* pusha */
                   4945:         if (CODE64(s))
                   4946:             goto illegal_op;
                   4947:         gen_pusha(s);
                   4948:         break;
                   4949:     case 0x61: /* popa */
                   4950:         if (CODE64(s))
                   4951:             goto illegal_op;
                   4952:         gen_popa(s);
                   4953:         break;
                   4954:     case 0x68: /* push Iv */
                   4955:     case 0x6a:
                   4956:         if (CODE64(s)) {
                   4957:             ot = dflag ? OT_QUAD : OT_WORD;
                   4958:         } else {
                   4959:             ot = dflag + OT_WORD;
                   4960:         }
                   4961:         if (b == 0x68)
                   4962:             val = insn_get(s, ot);
                   4963:         else
                   4964:             val = (int8_t)insn_get(s, OT_BYTE);
                   4965:         gen_op_movl_T0_im(val);
                   4966:         gen_push_T0(s);
                   4967:         break;
                   4968:     case 0x8f: /* pop Ev */
                   4969:         if (CODE64(s)) {
                   4970:             ot = dflag ? OT_QUAD : OT_WORD;
                   4971:         } else {
                   4972:             ot = dflag + OT_WORD;
                   4973:         }
                   4974:         modrm = ldub_code(s->pc++);
                   4975:         mod = (modrm >> 6) & 3;
                   4976:         gen_pop_T0(s);
                   4977:         if (mod == 3) {
                   4978:             /* NOTE: order is important for pop %sp */
                   4979:             gen_pop_update(s);
                   4980:             rm = (modrm & 7) | REX_B(s);
1.1.1.7   root     4981:             gen_op_mov_reg_T0(ot, rm);
1.1       root     4982:         } else {
                   4983:             /* NOTE: order is important too for MMU exceptions */
                   4984:             s->popl_esp_hack = 1 << ot;
                   4985:             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
                   4986:             s->popl_esp_hack = 0;
                   4987:             gen_pop_update(s);
                   4988:         }
                   4989:         break;
                   4990:     case 0xc8: /* enter */
                   4991:         {
                   4992:             int level;
                   4993:             val = lduw_code(s->pc);
                   4994:             s->pc += 2;
                   4995:             level = ldub_code(s->pc++);
                   4996:             gen_enter(s, val, level);
                   4997:         }
                   4998:         break;
                   4999:     case 0xc9: /* leave */
                   5000:         /* XXX: exception not precise (ESP is updated before potential exception) */
                   5001:         if (CODE64(s)) {
1.1.1.7   root     5002:             gen_op_mov_TN_reg(OT_QUAD, 0, R_EBP);
                   5003:             gen_op_mov_reg_T0(OT_QUAD, R_ESP);
1.1       root     5004:         } else if (s->ss32) {
1.1.1.7   root     5005:             gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
                   5006:             gen_op_mov_reg_T0(OT_LONG, R_ESP);
1.1       root     5007:         } else {
1.1.1.7   root     5008:             gen_op_mov_TN_reg(OT_WORD, 0, R_EBP);
                   5009:             gen_op_mov_reg_T0(OT_WORD, R_ESP);
1.1       root     5010:         }
                   5011:         gen_pop_T0(s);
                   5012:         if (CODE64(s)) {
                   5013:             ot = dflag ? OT_QUAD : OT_WORD;
                   5014:         } else {
                   5015:             ot = dflag + OT_WORD;
                   5016:         }
1.1.1.7   root     5017:         gen_op_mov_reg_T0(ot, R_EBP);
1.1       root     5018:         gen_pop_update(s);
                   5019:         break;
                   5020:     case 0x06: /* push es */
                   5021:     case 0x0e: /* push cs */
                   5022:     case 0x16: /* push ss */
                   5023:     case 0x1e: /* push ds */
                   5024:         if (CODE64(s))
                   5025:             goto illegal_op;
                   5026:         gen_op_movl_T0_seg(b >> 3);
                   5027:         gen_push_T0(s);
                   5028:         break;
                   5029:     case 0x1a0: /* push fs */
                   5030:     case 0x1a8: /* push gs */
                   5031:         gen_op_movl_T0_seg((b >> 3) & 7);
                   5032:         gen_push_T0(s);
                   5033:         break;
                   5034:     case 0x07: /* pop es */
                   5035:     case 0x17: /* pop ss */
                   5036:     case 0x1f: /* pop ds */
                   5037:         if (CODE64(s))
                   5038:             goto illegal_op;
                   5039:         reg = b >> 3;
                   5040:         gen_pop_T0(s);
                   5041:         gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
                   5042:         gen_pop_update(s);
                   5043:         if (reg == R_SS) {
                   5044:             /* if reg == SS, inhibit interrupts/trace. */
                   5045:             /* If several instructions disable interrupts, only the
                   5046:                _first_ does it */
                   5047:             if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
1.1.1.7   root     5048:                 gen_helper_set_inhibit_irq();
1.1       root     5049:             s->tf = 0;
                   5050:         }
                   5051:         if (s->is_jmp) {
                   5052:             gen_jmp_im(s->pc - s->cs_base);
                   5053:             gen_eob(s);
                   5054:         }
                   5055:         break;
                   5056:     case 0x1a1: /* pop fs */
                   5057:     case 0x1a9: /* pop gs */
                   5058:         gen_pop_T0(s);
                   5059:         gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
                   5060:         gen_pop_update(s);
                   5061:         if (s->is_jmp) {
                   5062:             gen_jmp_im(s->pc - s->cs_base);
                   5063:             gen_eob(s);
                   5064:         }
                   5065:         break;
                   5066: 
                   5067:         /**************************/
                   5068:         /* mov */
                   5069:     case 0x88:
                   5070:     case 0x89: /* mov Gv, Ev */
                   5071:         if ((b & 1) == 0)
                   5072:             ot = OT_BYTE;
                   5073:         else
                   5074:             ot = dflag + OT_WORD;
                   5075:         modrm = ldub_code(s->pc++);
                   5076:         reg = ((modrm >> 3) & 7) | rex_r;
1.1.1.6   root     5077: 
1.1       root     5078:         /* generate a generic store */
                   5079:         gen_ldst_modrm(s, modrm, ot, reg, 1);
                   5080:         break;
                   5081:     case 0xc6:
                   5082:     case 0xc7: /* mov Ev, Iv */
                   5083:         if ((b & 1) == 0)
                   5084:             ot = OT_BYTE;
                   5085:         else
                   5086:             ot = dflag + OT_WORD;
                   5087:         modrm = ldub_code(s->pc++);
                   5088:         mod = (modrm >> 6) & 3;
                   5089:         if (mod != 3) {
                   5090:             s->rip_offset = insn_const_size(ot);
                   5091:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5092:         }
                   5093:         val = insn_get(s, ot);
                   5094:         gen_op_movl_T0_im(val);
                   5095:         if (mod != 3)
1.1.1.7   root     5096:             gen_op_st_T0_A0(ot + s->mem_index);
1.1       root     5097:         else
1.1.1.7   root     5098:             gen_op_mov_reg_T0(ot, (modrm & 7) | REX_B(s));
1.1       root     5099:         break;
                   5100:     case 0x8a:
                   5101:     case 0x8b: /* mov Ev, Gv */
                   5102:         if ((b & 1) == 0)
                   5103:             ot = OT_BYTE;
                   5104:         else
                   5105:             ot = OT_WORD + dflag;
                   5106:         modrm = ldub_code(s->pc++);
                   5107:         reg = ((modrm >> 3) & 7) | rex_r;
1.1.1.6   root     5108: 
1.1       root     5109:         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1.1.1.7   root     5110:         gen_op_mov_reg_T0(ot, reg);
1.1       root     5111:         break;
                   5112:     case 0x8e: /* mov seg, Gv */
                   5113:         modrm = ldub_code(s->pc++);
                   5114:         reg = (modrm >> 3) & 7;
                   5115:         if (reg >= 6 || reg == R_CS)
                   5116:             goto illegal_op;
                   5117:         gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
                   5118:         gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
                   5119:         if (reg == R_SS) {
                   5120:             /* if reg == SS, inhibit interrupts/trace */
                   5121:             /* If several instructions disable interrupts, only the
                   5122:                _first_ does it */
                   5123:             if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
1.1.1.7   root     5124:                 gen_helper_set_inhibit_irq();
1.1       root     5125:             s->tf = 0;
                   5126:         }
                   5127:         if (s->is_jmp) {
                   5128:             gen_jmp_im(s->pc - s->cs_base);
                   5129:             gen_eob(s);
                   5130:         }
                   5131:         break;
                   5132:     case 0x8c: /* mov Gv, seg */
                   5133:         modrm = ldub_code(s->pc++);
                   5134:         reg = (modrm >> 3) & 7;
                   5135:         mod = (modrm >> 6) & 3;
                   5136:         if (reg >= 6)
                   5137:             goto illegal_op;
                   5138:         gen_op_movl_T0_seg(reg);
                   5139:         if (mod == 3)
                   5140:             ot = OT_WORD + dflag;
                   5141:         else
                   5142:             ot = OT_WORD;
                   5143:         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
                   5144:         break;
                   5145: 
                   5146:     case 0x1b6: /* movzbS Gv, Eb */
                   5147:     case 0x1b7: /* movzwS Gv, Eb */
                   5148:     case 0x1be: /* movsbS Gv, Eb */
                   5149:     case 0x1bf: /* movswS Gv, Eb */
                   5150:         {
                   5151:             int d_ot;
                   5152:             /* d_ot is the size of destination */
                   5153:             d_ot = dflag + OT_WORD;
                   5154:             /* ot is the size of source */
                   5155:             ot = (b & 1) + OT_BYTE;
                   5156:             modrm = ldub_code(s->pc++);
                   5157:             reg = ((modrm >> 3) & 7) | rex_r;
                   5158:             mod = (modrm >> 6) & 3;
                   5159:             rm = (modrm & 7) | REX_B(s);
1.1.1.6   root     5160: 
1.1       root     5161:             if (mod == 3) {
1.1.1.7   root     5162:                 gen_op_mov_TN_reg(ot, 0, rm);
1.1       root     5163:                 switch(ot | (b & 8)) {
                   5164:                 case OT_BYTE:
1.1.1.7   root     5165:                     tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
1.1       root     5166:                     break;
                   5167:                 case OT_BYTE | 8:
1.1.1.7   root     5168:                     tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
1.1       root     5169:                     break;
                   5170:                 case OT_WORD:
1.1.1.7   root     5171:                     tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
1.1       root     5172:                     break;
                   5173:                 default:
                   5174:                 case OT_WORD | 8:
1.1.1.7   root     5175:                     tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
1.1       root     5176:                     break;
                   5177:                 }
1.1.1.7   root     5178:                 gen_op_mov_reg_T0(d_ot, reg);
1.1       root     5179:             } else {
                   5180:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5181:                 if (b & 8) {
1.1.1.7   root     5182:                     gen_op_lds_T0_A0(ot + s->mem_index);
1.1       root     5183:                 } else {
1.1.1.7   root     5184:                     gen_op_ldu_T0_A0(ot + s->mem_index);
1.1       root     5185:                 }
1.1.1.7   root     5186:                 gen_op_mov_reg_T0(d_ot, reg);
1.1       root     5187:             }
                   5188:         }
                   5189:         break;
                   5190: 
                   5191:     case 0x8d: /* lea */
                   5192:         ot = dflag + OT_WORD;
                   5193:         modrm = ldub_code(s->pc++);
                   5194:         mod = (modrm >> 6) & 3;
                   5195:         if (mod == 3)
                   5196:             goto illegal_op;
                   5197:         reg = ((modrm >> 3) & 7) | rex_r;
                   5198:         /* we must ensure that no segment is added */
                   5199:         s->override = -1;
                   5200:         val = s->addseg;
                   5201:         s->addseg = 0;
                   5202:         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5203:         s->addseg = val;
1.1.1.7   root     5204:         gen_op_mov_reg_A0(ot - OT_WORD, reg);
1.1       root     5205:         break;
1.1.1.6   root     5206: 
1.1       root     5207:     case 0xa0: /* mov EAX, Ov */
                   5208:     case 0xa1:
                   5209:     case 0xa2: /* mov Ov, EAX */
                   5210:     case 0xa3:
                   5211:         {
                   5212:             target_ulong offset_addr;
                   5213: 
                   5214:             if ((b & 1) == 0)
                   5215:                 ot = OT_BYTE;
                   5216:             else
                   5217:                 ot = dflag + OT_WORD;
                   5218: #ifdef TARGET_X86_64
                   5219:             if (s->aflag == 2) {
                   5220:                 offset_addr = ldq_code(s->pc);
                   5221:                 s->pc += 8;
1.1.1.7   root     5222:                 gen_op_movq_A0_im(offset_addr);
1.1.1.6   root     5223:             } else
1.1       root     5224: #endif
                   5225:             {
                   5226:                 if (s->aflag) {
                   5227:                     offset_addr = insn_get(s, OT_LONG);
                   5228:                 } else {
                   5229:                     offset_addr = insn_get(s, OT_WORD);
                   5230:                 }
                   5231:                 gen_op_movl_A0_im(offset_addr);
                   5232:             }
                   5233:             gen_add_A0_ds_seg(s);
                   5234:             if ((b & 2) == 0) {
1.1.1.7   root     5235:                 gen_op_ld_T0_A0(ot + s->mem_index);
                   5236:                 gen_op_mov_reg_T0(ot, R_EAX);
1.1       root     5237:             } else {
1.1.1.7   root     5238:                 gen_op_mov_TN_reg(ot, 0, R_EAX);
                   5239:                 gen_op_st_T0_A0(ot + s->mem_index);
1.1       root     5240:             }
                   5241:         }
                   5242:         break;
                   5243:     case 0xd7: /* xlat */
                   5244: #ifdef TARGET_X86_64
                   5245:         if (s->aflag == 2) {
1.1.1.7   root     5246:             gen_op_movq_A0_reg(R_EBX);
                   5247:             gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
                   5248:             tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
                   5249:             tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
1.1.1.6   root     5250:         } else
1.1       root     5251: #endif
                   5252:         {
1.1.1.7   root     5253:             gen_op_movl_A0_reg(R_EBX);
                   5254:             gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
                   5255:             tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
                   5256:             tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
1.1       root     5257:             if (s->aflag == 0)
                   5258:                 gen_op_andl_A0_ffff();
1.1.1.7   root     5259:             else
                   5260:                 tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
1.1       root     5261:         }
                   5262:         gen_add_A0_ds_seg(s);
1.1.1.7   root     5263:         gen_op_ldu_T0_A0(OT_BYTE + s->mem_index);
                   5264:         gen_op_mov_reg_T0(OT_BYTE, R_EAX);
1.1       root     5265:         break;
                   5266:     case 0xb0 ... 0xb7: /* mov R, Ib */
                   5267:         val = insn_get(s, OT_BYTE);
                   5268:         gen_op_movl_T0_im(val);
1.1.1.7   root     5269:         gen_op_mov_reg_T0(OT_BYTE, (b & 7) | REX_B(s));
1.1       root     5270:         break;
                   5271:     case 0xb8 ... 0xbf: /* mov R, Iv */
                   5272: #ifdef TARGET_X86_64
                   5273:         if (dflag == 2) {
                   5274:             uint64_t tmp;
                   5275:             /* 64 bit case */
                   5276:             tmp = ldq_code(s->pc);
                   5277:             s->pc += 8;
                   5278:             reg = (b & 7) | REX_B(s);
                   5279:             gen_movtl_T0_im(tmp);
1.1.1.7   root     5280:             gen_op_mov_reg_T0(OT_QUAD, reg);
1.1.1.6   root     5281:         } else
1.1       root     5282: #endif
                   5283:         {
                   5284:             ot = dflag ? OT_LONG : OT_WORD;
                   5285:             val = insn_get(s, ot);
                   5286:             reg = (b & 7) | REX_B(s);
                   5287:             gen_op_movl_T0_im(val);
1.1.1.7   root     5288:             gen_op_mov_reg_T0(ot, reg);
1.1       root     5289:         }
                   5290:         break;
                   5291: 
                   5292:     case 0x91 ... 0x97: /* xchg R, EAX */
1.1.1.12  root     5293:     do_xchg_reg_eax:
1.1       root     5294:         ot = dflag + OT_WORD;
                   5295:         reg = (b & 7) | REX_B(s);
                   5296:         rm = R_EAX;
                   5297:         goto do_xchg_reg;
                   5298:     case 0x86:
                   5299:     case 0x87: /* xchg Ev, Gv */
                   5300:         if ((b & 1) == 0)
                   5301:             ot = OT_BYTE;
                   5302:         else
                   5303:             ot = dflag + OT_WORD;
                   5304:         modrm = ldub_code(s->pc++);
                   5305:         reg = ((modrm >> 3) & 7) | rex_r;
                   5306:         mod = (modrm >> 6) & 3;
                   5307:         if (mod == 3) {
                   5308:             rm = (modrm & 7) | REX_B(s);
                   5309:         do_xchg_reg:
1.1.1.7   root     5310:             gen_op_mov_TN_reg(ot, 0, reg);
                   5311:             gen_op_mov_TN_reg(ot, 1, rm);
                   5312:             gen_op_mov_reg_T0(ot, rm);
                   5313:             gen_op_mov_reg_T1(ot, reg);
1.1       root     5314:         } else {
                   5315:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     5316:             gen_op_mov_TN_reg(ot, 0, reg);
1.1       root     5317:             /* for xchg, lock is implicit */
                   5318:             if (!(prefixes & PREFIX_LOCK))
1.1.1.7   root     5319:                 gen_helper_lock();
                   5320:             gen_op_ld_T1_A0(ot + s->mem_index);
                   5321:             gen_op_st_T0_A0(ot + s->mem_index);
1.1       root     5322:             if (!(prefixes & PREFIX_LOCK))
1.1.1.7   root     5323:                 gen_helper_unlock();
                   5324:             gen_op_mov_reg_T1(ot, reg);
1.1       root     5325:         }
                   5326:         break;
                   5327:     case 0xc4: /* les Gv */
                   5328:         if (CODE64(s))
                   5329:             goto illegal_op;
                   5330:         op = R_ES;
                   5331:         goto do_lxx;
                   5332:     case 0xc5: /* lds Gv */
                   5333:         if (CODE64(s))
                   5334:             goto illegal_op;
                   5335:         op = R_DS;
                   5336:         goto do_lxx;
                   5337:     case 0x1b2: /* lss Gv */
                   5338:         op = R_SS;
                   5339:         goto do_lxx;
                   5340:     case 0x1b4: /* lfs Gv */
                   5341:         op = R_FS;
                   5342:         goto do_lxx;
                   5343:     case 0x1b5: /* lgs Gv */
                   5344:         op = R_GS;
                   5345:     do_lxx:
                   5346:         ot = dflag ? OT_LONG : OT_WORD;
                   5347:         modrm = ldub_code(s->pc++);
                   5348:         reg = ((modrm >> 3) & 7) | rex_r;
                   5349:         mod = (modrm >> 6) & 3;
                   5350:         if (mod == 3)
                   5351:             goto illegal_op;
                   5352:         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     5353:         gen_op_ld_T1_A0(ot + s->mem_index);
1.1       root     5354:         gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
                   5355:         /* load the segment first to handle exceptions properly */
1.1.1.7   root     5356:         gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
1.1       root     5357:         gen_movl_seg_T0(s, op, pc_start - s->cs_base);
                   5358:         /* then put the data */
1.1.1.7   root     5359:         gen_op_mov_reg_T1(ot, reg);
1.1       root     5360:         if (s->is_jmp) {
                   5361:             gen_jmp_im(s->pc - s->cs_base);
                   5362:             gen_eob(s);
                   5363:         }
                   5364:         break;
1.1.1.6   root     5365: 
1.1       root     5366:         /************************/
                   5367:         /* shifts */
                   5368:     case 0xc0:
                   5369:     case 0xc1:
                   5370:         /* shift Ev,Ib */
                   5371:         shift = 2;
                   5372:     grp2:
                   5373:         {
                   5374:             if ((b & 1) == 0)
                   5375:                 ot = OT_BYTE;
                   5376:             else
                   5377:                 ot = dflag + OT_WORD;
1.1.1.6   root     5378: 
1.1       root     5379:             modrm = ldub_code(s->pc++);
                   5380:             mod = (modrm >> 6) & 3;
                   5381:             op = (modrm >> 3) & 7;
1.1.1.6   root     5382: 
1.1       root     5383:             if (mod != 3) {
                   5384:                 if (shift == 2) {
                   5385:                     s->rip_offset = 1;
                   5386:                 }
                   5387:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5388:                 opreg = OR_TMP0;
                   5389:             } else {
                   5390:                 opreg = (modrm & 7) | REX_B(s);
                   5391:             }
                   5392: 
                   5393:             /* simpler op */
                   5394:             if (shift == 0) {
                   5395:                 gen_shift(s, op, ot, opreg, OR_ECX);
                   5396:             } else {
                   5397:                 if (shift == 2) {
                   5398:                     shift = ldub_code(s->pc++);
                   5399:                 }
                   5400:                 gen_shifti(s, op, ot, opreg, shift);
                   5401:             }
                   5402:         }
                   5403:         break;
                   5404:     case 0xd0:
                   5405:     case 0xd1:
                   5406:         /* shift Ev,1 */
                   5407:         shift = 1;
                   5408:         goto grp2;
                   5409:     case 0xd2:
                   5410:     case 0xd3:
                   5411:         /* shift Ev,cl */
                   5412:         shift = 0;
                   5413:         goto grp2;
                   5414: 
                   5415:     case 0x1a4: /* shld imm */
                   5416:         op = 0;
                   5417:         shift = 1;
                   5418:         goto do_shiftd;
                   5419:     case 0x1a5: /* shld cl */
                   5420:         op = 0;
                   5421:         shift = 0;
                   5422:         goto do_shiftd;
                   5423:     case 0x1ac: /* shrd imm */
                   5424:         op = 1;
                   5425:         shift = 1;
                   5426:         goto do_shiftd;
                   5427:     case 0x1ad: /* shrd cl */
                   5428:         op = 1;
                   5429:         shift = 0;
                   5430:     do_shiftd:
                   5431:         ot = dflag + OT_WORD;
                   5432:         modrm = ldub_code(s->pc++);
                   5433:         mod = (modrm >> 6) & 3;
                   5434:         rm = (modrm & 7) | REX_B(s);
                   5435:         reg = ((modrm >> 3) & 7) | rex_r;
                   5436:         if (mod != 3) {
                   5437:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     5438:             opreg = OR_TMP0;
1.1       root     5439:         } else {
1.1.1.7   root     5440:             opreg = rm;
1.1       root     5441:         }
1.1.1.7   root     5442:         gen_op_mov_TN_reg(ot, 1, reg);
1.1.1.6   root     5443: 
1.1       root     5444:         if (shift) {
                   5445:             val = ldub_code(s->pc++);
1.1.1.7   root     5446:             tcg_gen_movi_tl(cpu_T3, val);
1.1       root     5447:         } else {
1.1.1.9   root     5448:             tcg_gen_mov_tl(cpu_T3, cpu_regs[R_ECX]);
1.1       root     5449:         }
1.1.1.7   root     5450:         gen_shiftd_rm_T1_T3(s, ot, opreg, op);
1.1       root     5451:         break;
                   5452: 
                   5453:         /************************/
                   5454:         /* floats */
1.1.1.6   root     5455:     case 0xd8 ... 0xdf:
1.1       root     5456:         if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
                   5457:             /* if CR0.EM or CR0.TS are set, generate an FPU exception */
                   5458:             /* XXX: what to do if illegal op ? */
                   5459:             gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
                   5460:             break;
                   5461:         }
                   5462:         modrm = ldub_code(s->pc++);
                   5463:         mod = (modrm >> 6) & 3;
                   5464:         rm = modrm & 7;
                   5465:         op = ((b & 7) << 3) | ((modrm >> 3) & 7);
                   5466:         if (mod != 3) {
                   5467:             /* memory op */
                   5468:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5469:             switch(op) {
                   5470:             case 0x00 ... 0x07: /* fxxxs */
                   5471:             case 0x10 ... 0x17: /* fixxxl */
                   5472:             case 0x20 ... 0x27: /* fxxxl */
                   5473:             case 0x30 ... 0x37: /* fixxx */
                   5474:                 {
                   5475:                     int op1;
                   5476:                     op1 = op & 7;
                   5477: 
                   5478:                     switch(op >> 4) {
                   5479:                     case 0:
1.1.1.7   root     5480:                         gen_op_ld_T0_A0(OT_LONG + s->mem_index);
                   5481:                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   5482:                         gen_helper_flds_FT0(cpu_tmp2_i32);
1.1       root     5483:                         break;
                   5484:                     case 1:
1.1.1.7   root     5485:                         gen_op_ld_T0_A0(OT_LONG + s->mem_index);
                   5486:                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   5487:                         gen_helper_fildl_FT0(cpu_tmp2_i32);
1.1       root     5488:                         break;
                   5489:                     case 2:
1.1.1.7   root     5490:                         tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
                   5491:                                           (s->mem_index >> 2) - 1);
                   5492:                         gen_helper_fldl_FT0(cpu_tmp1_i64);
1.1       root     5493:                         break;
                   5494:                     case 3:
                   5495:                     default:
1.1.1.7   root     5496:                         gen_op_lds_T0_A0(OT_WORD + s->mem_index);
                   5497:                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   5498:                         gen_helper_fildl_FT0(cpu_tmp2_i32);
1.1       root     5499:                         break;
                   5500:                     }
1.1.1.6   root     5501: 
1.1.1.7   root     5502:                     gen_helper_fp_arith_ST0_FT0(op1);
1.1       root     5503:                     if (op1 == 3) {
                   5504:                         /* fcomp needs pop */
1.1.1.7   root     5505:                         gen_helper_fpop();
1.1       root     5506:                     }
                   5507:                 }
                   5508:                 break;
                   5509:             case 0x08: /* flds */
                   5510:             case 0x0a: /* fsts */
                   5511:             case 0x0b: /* fstps */
1.1.1.3   root     5512:             case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
                   5513:             case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
                   5514:             case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
1.1       root     5515:                 switch(op & 7) {
                   5516:                 case 0:
                   5517:                     switch(op >> 4) {
                   5518:                     case 0:
1.1.1.7   root     5519:                         gen_op_ld_T0_A0(OT_LONG + s->mem_index);
                   5520:                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   5521:                         gen_helper_flds_ST0(cpu_tmp2_i32);
1.1       root     5522:                         break;
                   5523:                     case 1:
1.1.1.7   root     5524:                         gen_op_ld_T0_A0(OT_LONG + s->mem_index);
                   5525:                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   5526:                         gen_helper_fildl_ST0(cpu_tmp2_i32);
1.1       root     5527:                         break;
                   5528:                     case 2:
1.1.1.7   root     5529:                         tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
                   5530:                                           (s->mem_index >> 2) - 1);
                   5531:                         gen_helper_fldl_ST0(cpu_tmp1_i64);
1.1       root     5532:                         break;
                   5533:                     case 3:
                   5534:                     default:
1.1.1.7   root     5535:                         gen_op_lds_T0_A0(OT_WORD + s->mem_index);
                   5536:                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   5537:                         gen_helper_fildl_ST0(cpu_tmp2_i32);
1.1       root     5538:                         break;
                   5539:                     }
                   5540:                     break;
1.1.1.3   root     5541:                 case 1:
1.1.1.7   root     5542:                     /* XXX: the corresponding CPUID bit must be tested ! */
1.1.1.3   root     5543:                     switch(op >> 4) {
                   5544:                     case 1:
1.1.1.7   root     5545:                         gen_helper_fisttl_ST0(cpu_tmp2_i32);
                   5546:                         tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
                   5547:                         gen_op_st_T0_A0(OT_LONG + s->mem_index);
1.1.1.3   root     5548:                         break;
                   5549:                     case 2:
1.1.1.7   root     5550:                         gen_helper_fisttll_ST0(cpu_tmp1_i64);
                   5551:                         tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
                   5552:                                           (s->mem_index >> 2) - 1);
1.1.1.3   root     5553:                         break;
                   5554:                     case 3:
                   5555:                     default:
1.1.1.7   root     5556:                         gen_helper_fistt_ST0(cpu_tmp2_i32);
                   5557:                         tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
                   5558:                         gen_op_st_T0_A0(OT_WORD + s->mem_index);
                   5559:                         break;
1.1.1.3   root     5560:                     }
1.1.1.7   root     5561:                     gen_helper_fpop();
1.1.1.3   root     5562:                     break;
1.1       root     5563:                 default:
                   5564:                     switch(op >> 4) {
                   5565:                     case 0:
1.1.1.7   root     5566:                         gen_helper_fsts_ST0(cpu_tmp2_i32);
                   5567:                         tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
                   5568:                         gen_op_st_T0_A0(OT_LONG + s->mem_index);
1.1       root     5569:                         break;
                   5570:                     case 1:
1.1.1.7   root     5571:                         gen_helper_fistl_ST0(cpu_tmp2_i32);
                   5572:                         tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
                   5573:                         gen_op_st_T0_A0(OT_LONG + s->mem_index);
1.1       root     5574:                         break;
                   5575:                     case 2:
1.1.1.7   root     5576:                         gen_helper_fstl_ST0(cpu_tmp1_i64);
                   5577:                         tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
                   5578:                                           (s->mem_index >> 2) - 1);
1.1       root     5579:                         break;
                   5580:                     case 3:
                   5581:                     default:
1.1.1.7   root     5582:                         gen_helper_fist_ST0(cpu_tmp2_i32);
                   5583:                         tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
                   5584:                         gen_op_st_T0_A0(OT_WORD + s->mem_index);
1.1       root     5585:                         break;
                   5586:                     }
                   5587:                     if ((op & 7) == 3)
1.1.1.7   root     5588:                         gen_helper_fpop();
1.1       root     5589:                     break;
                   5590:                 }
                   5591:                 break;
                   5592:             case 0x0c: /* fldenv mem */
1.1.1.7   root     5593:                 if (s->cc_op != CC_OP_DYNAMIC)
                   5594:                     gen_op_set_cc_op(s->cc_op);
                   5595:                 gen_jmp_im(pc_start - s->cs_base);
                   5596:                 gen_helper_fldenv(
                   5597:                                    cpu_A0, tcg_const_i32(s->dflag));
1.1       root     5598:                 break;
                   5599:             case 0x0d: /* fldcw mem */
1.1.1.7   root     5600:                 gen_op_ld_T0_A0(OT_WORD + s->mem_index);
                   5601:                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   5602:                 gen_helper_fldcw(cpu_tmp2_i32);
1.1       root     5603:                 break;
                   5604:             case 0x0e: /* fnstenv mem */
1.1.1.7   root     5605:                 if (s->cc_op != CC_OP_DYNAMIC)
                   5606:                     gen_op_set_cc_op(s->cc_op);
                   5607:                 gen_jmp_im(pc_start - s->cs_base);
                   5608:                 gen_helper_fstenv(cpu_A0, tcg_const_i32(s->dflag));
1.1       root     5609:                 break;
                   5610:             case 0x0f: /* fnstcw mem */
1.1.1.7   root     5611:                 gen_helper_fnstcw(cpu_tmp2_i32);
                   5612:                 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
                   5613:                 gen_op_st_T0_A0(OT_WORD + s->mem_index);
1.1       root     5614:                 break;
                   5615:             case 0x1d: /* fldt mem */
1.1.1.7   root     5616:                 if (s->cc_op != CC_OP_DYNAMIC)
                   5617:                     gen_op_set_cc_op(s->cc_op);
                   5618:                 gen_jmp_im(pc_start - s->cs_base);
                   5619:                 gen_helper_fldt_ST0(cpu_A0);
1.1       root     5620:                 break;
                   5621:             case 0x1f: /* fstpt mem */
1.1.1.7   root     5622:                 if (s->cc_op != CC_OP_DYNAMIC)
                   5623:                     gen_op_set_cc_op(s->cc_op);
                   5624:                 gen_jmp_im(pc_start - s->cs_base);
                   5625:                 gen_helper_fstt_ST0(cpu_A0);
                   5626:                 gen_helper_fpop();
1.1       root     5627:                 break;
                   5628:             case 0x2c: /* frstor mem */
1.1.1.7   root     5629:                 if (s->cc_op != CC_OP_DYNAMIC)
                   5630:                     gen_op_set_cc_op(s->cc_op);
                   5631:                 gen_jmp_im(pc_start - s->cs_base);
                   5632:                 gen_helper_frstor(cpu_A0, tcg_const_i32(s->dflag));
1.1       root     5633:                 break;
                   5634:             case 0x2e: /* fnsave mem */
1.1.1.7   root     5635:                 if (s->cc_op != CC_OP_DYNAMIC)
                   5636:                     gen_op_set_cc_op(s->cc_op);
                   5637:                 gen_jmp_im(pc_start - s->cs_base);
                   5638:                 gen_helper_fsave(cpu_A0, tcg_const_i32(s->dflag));
1.1       root     5639:                 break;
                   5640:             case 0x2f: /* fnstsw mem */
1.1.1.7   root     5641:                 gen_helper_fnstsw(cpu_tmp2_i32);
                   5642:                 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
                   5643:                 gen_op_st_T0_A0(OT_WORD + s->mem_index);
1.1       root     5644:                 break;
                   5645:             case 0x3c: /* fbld */
1.1.1.7   root     5646:                 if (s->cc_op != CC_OP_DYNAMIC)
                   5647:                     gen_op_set_cc_op(s->cc_op);
                   5648:                 gen_jmp_im(pc_start - s->cs_base);
                   5649:                 gen_helper_fbld_ST0(cpu_A0);
1.1       root     5650:                 break;
                   5651:             case 0x3e: /* fbstp */
1.1.1.7   root     5652:                 if (s->cc_op != CC_OP_DYNAMIC)
                   5653:                     gen_op_set_cc_op(s->cc_op);
                   5654:                 gen_jmp_im(pc_start - s->cs_base);
                   5655:                 gen_helper_fbst_ST0(cpu_A0);
                   5656:                 gen_helper_fpop();
1.1       root     5657:                 break;
                   5658:             case 0x3d: /* fildll */
1.1.1.7   root     5659:                 tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
                   5660:                                   (s->mem_index >> 2) - 1);
                   5661:                 gen_helper_fildll_ST0(cpu_tmp1_i64);
1.1       root     5662:                 break;
                   5663:             case 0x3f: /* fistpll */
1.1.1.7   root     5664:                 gen_helper_fistll_ST0(cpu_tmp1_i64);
                   5665:                 tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
                   5666:                                   (s->mem_index >> 2) - 1);
                   5667:                 gen_helper_fpop();
1.1       root     5668:                 break;
                   5669:             default:
                   5670:                 goto illegal_op;
                   5671:             }
                   5672:         } else {
                   5673:             /* register float ops */
                   5674:             opreg = rm;
                   5675: 
                   5676:             switch(op) {
                   5677:             case 0x08: /* fld sti */
1.1.1.7   root     5678:                 gen_helper_fpush();
                   5679:                 gen_helper_fmov_ST0_STN(tcg_const_i32((opreg + 1) & 7));
1.1       root     5680:                 break;
                   5681:             case 0x09: /* fxchg sti */
                   5682:             case 0x29: /* fxchg4 sti, undocumented op */
                   5683:             case 0x39: /* fxchg7 sti, undocumented op */
1.1.1.7   root     5684:                 gen_helper_fxchg_ST0_STN(tcg_const_i32(opreg));
1.1       root     5685:                 break;
                   5686:             case 0x0a: /* grp d9/2 */
                   5687:                 switch(rm) {
                   5688:                 case 0: /* fnop */
                   5689:                     /* check exceptions (FreeBSD FPU probe) */
                   5690:                     if (s->cc_op != CC_OP_DYNAMIC)
                   5691:                         gen_op_set_cc_op(s->cc_op);
                   5692:                     gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     5693:                     gen_helper_fwait();
1.1       root     5694:                     break;
                   5695:                 default:
                   5696:                     goto illegal_op;
                   5697:                 }
                   5698:                 break;
                   5699:             case 0x0c: /* grp d9/4 */
                   5700:                 switch(rm) {
                   5701:                 case 0: /* fchs */
1.1.1.7   root     5702:                     gen_helper_fchs_ST0();
1.1       root     5703:                     break;
                   5704:                 case 1: /* fabs */
1.1.1.7   root     5705:                     gen_helper_fabs_ST0();
1.1       root     5706:                     break;
                   5707:                 case 4: /* ftst */
1.1.1.7   root     5708:                     gen_helper_fldz_FT0();
                   5709:                     gen_helper_fcom_ST0_FT0();
1.1       root     5710:                     break;
                   5711:                 case 5: /* fxam */
1.1.1.7   root     5712:                     gen_helper_fxam_ST0();
1.1       root     5713:                     break;
                   5714:                 default:
                   5715:                     goto illegal_op;
                   5716:                 }
                   5717:                 break;
                   5718:             case 0x0d: /* grp d9/5 */
                   5719:                 {
                   5720:                     switch(rm) {
                   5721:                     case 0:
1.1.1.7   root     5722:                         gen_helper_fpush();
                   5723:                         gen_helper_fld1_ST0();
1.1       root     5724:                         break;
                   5725:                     case 1:
1.1.1.7   root     5726:                         gen_helper_fpush();
                   5727:                         gen_helper_fldl2t_ST0();
1.1       root     5728:                         break;
                   5729:                     case 2:
1.1.1.7   root     5730:                         gen_helper_fpush();
                   5731:                         gen_helper_fldl2e_ST0();
1.1       root     5732:                         break;
                   5733:                     case 3:
1.1.1.7   root     5734:                         gen_helper_fpush();
                   5735:                         gen_helper_fldpi_ST0();
1.1       root     5736:                         break;
                   5737:                     case 4:
1.1.1.7   root     5738:                         gen_helper_fpush();
                   5739:                         gen_helper_fldlg2_ST0();
1.1       root     5740:                         break;
                   5741:                     case 5:
1.1.1.7   root     5742:                         gen_helper_fpush();
                   5743:                         gen_helper_fldln2_ST0();
1.1       root     5744:                         break;
                   5745:                     case 6:
1.1.1.7   root     5746:                         gen_helper_fpush();
                   5747:                         gen_helper_fldz_ST0();
1.1       root     5748:                         break;
                   5749:                     default:
                   5750:                         goto illegal_op;
                   5751:                     }
                   5752:                 }
                   5753:                 break;
                   5754:             case 0x0e: /* grp d9/6 */
                   5755:                 switch(rm) {
                   5756:                 case 0: /* f2xm1 */
1.1.1.7   root     5757:                     gen_helper_f2xm1();
1.1       root     5758:                     break;
                   5759:                 case 1: /* fyl2x */
1.1.1.7   root     5760:                     gen_helper_fyl2x();
1.1       root     5761:                     break;
                   5762:                 case 2: /* fptan */
1.1.1.7   root     5763:                     gen_helper_fptan();
1.1       root     5764:                     break;
                   5765:                 case 3: /* fpatan */
1.1.1.7   root     5766:                     gen_helper_fpatan();
1.1       root     5767:                     break;
                   5768:                 case 4: /* fxtract */
1.1.1.7   root     5769:                     gen_helper_fxtract();
1.1       root     5770:                     break;
                   5771:                 case 5: /* fprem1 */
1.1.1.7   root     5772:                     gen_helper_fprem1();
1.1       root     5773:                     break;
                   5774:                 case 6: /* fdecstp */
1.1.1.7   root     5775:                     gen_helper_fdecstp();
1.1       root     5776:                     break;
                   5777:                 default:
                   5778:                 case 7: /* fincstp */
1.1.1.7   root     5779:                     gen_helper_fincstp();
1.1       root     5780:                     break;
                   5781:                 }
                   5782:                 break;
                   5783:             case 0x0f: /* grp d9/7 */
                   5784:                 switch(rm) {
                   5785:                 case 0: /* fprem */
1.1.1.7   root     5786:                     gen_helper_fprem();
1.1       root     5787:                     break;
                   5788:                 case 1: /* fyl2xp1 */
1.1.1.7   root     5789:                     gen_helper_fyl2xp1();
1.1       root     5790:                     break;
                   5791:                 case 2: /* fsqrt */
1.1.1.7   root     5792:                     gen_helper_fsqrt();
1.1       root     5793:                     break;
                   5794:                 case 3: /* fsincos */
1.1.1.7   root     5795:                     gen_helper_fsincos();
1.1       root     5796:                     break;
                   5797:                 case 5: /* fscale */
1.1.1.7   root     5798:                     gen_helper_fscale();
1.1       root     5799:                     break;
                   5800:                 case 4: /* frndint */
1.1.1.7   root     5801:                     gen_helper_frndint();
1.1       root     5802:                     break;
                   5803:                 case 6: /* fsin */
1.1.1.7   root     5804:                     gen_helper_fsin();
1.1       root     5805:                     break;
                   5806:                 default:
                   5807:                 case 7: /* fcos */
1.1.1.7   root     5808:                     gen_helper_fcos();
1.1       root     5809:                     break;
                   5810:                 }
                   5811:                 break;
                   5812:             case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
                   5813:             case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
                   5814:             case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
                   5815:                 {
                   5816:                     int op1;
1.1.1.6   root     5817: 
1.1       root     5818:                     op1 = op & 7;
                   5819:                     if (op >= 0x20) {
1.1.1.7   root     5820:                         gen_helper_fp_arith_STN_ST0(op1, opreg);
1.1       root     5821:                         if (op >= 0x30)
1.1.1.7   root     5822:                             gen_helper_fpop();
1.1       root     5823:                     } else {
1.1.1.7   root     5824:                         gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
                   5825:                         gen_helper_fp_arith_ST0_FT0(op1);
1.1       root     5826:                     }
                   5827:                 }
                   5828:                 break;
                   5829:             case 0x02: /* fcom */
                   5830:             case 0x22: /* fcom2, undocumented op */
1.1.1.7   root     5831:                 gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
                   5832:                 gen_helper_fcom_ST0_FT0();
1.1       root     5833:                 break;
                   5834:             case 0x03: /* fcomp */
                   5835:             case 0x23: /* fcomp3, undocumented op */
                   5836:             case 0x32: /* fcomp5, undocumented op */
1.1.1.7   root     5837:                 gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
                   5838:                 gen_helper_fcom_ST0_FT0();
                   5839:                 gen_helper_fpop();
1.1       root     5840:                 break;
                   5841:             case 0x15: /* da/5 */
                   5842:                 switch(rm) {
                   5843:                 case 1: /* fucompp */
1.1.1.7   root     5844:                     gen_helper_fmov_FT0_STN(tcg_const_i32(1));
                   5845:                     gen_helper_fucom_ST0_FT0();
                   5846:                     gen_helper_fpop();
                   5847:                     gen_helper_fpop();
1.1       root     5848:                     break;
                   5849:                 default:
                   5850:                     goto illegal_op;
                   5851:                 }
                   5852:                 break;
                   5853:             case 0x1c:
                   5854:                 switch(rm) {
                   5855:                 case 0: /* feni (287 only, just do nop here) */
                   5856:                     break;
                   5857:                 case 1: /* fdisi (287 only, just do nop here) */
                   5858:                     break;
                   5859:                 case 2: /* fclex */
1.1.1.7   root     5860:                     gen_helper_fclex();
1.1       root     5861:                     break;
                   5862:                 case 3: /* fninit */
1.1.1.7   root     5863:                     gen_helper_fninit();
1.1       root     5864:                     break;
                   5865:                 case 4: /* fsetpm (287 only, just do nop here) */
                   5866:                     break;
                   5867:                 default:
                   5868:                     goto illegal_op;
                   5869:                 }
                   5870:                 break;
                   5871:             case 0x1d: /* fucomi */
                   5872:                 if (s->cc_op != CC_OP_DYNAMIC)
                   5873:                     gen_op_set_cc_op(s->cc_op);
1.1.1.7   root     5874:                 gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
                   5875:                 gen_helper_fucomi_ST0_FT0();
1.1       root     5876:                 s->cc_op = CC_OP_EFLAGS;
                   5877:                 break;
                   5878:             case 0x1e: /* fcomi */
                   5879:                 if (s->cc_op != CC_OP_DYNAMIC)
                   5880:                     gen_op_set_cc_op(s->cc_op);
1.1.1.7   root     5881:                 gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
                   5882:                 gen_helper_fcomi_ST0_FT0();
1.1       root     5883:                 s->cc_op = CC_OP_EFLAGS;
                   5884:                 break;
                   5885:             case 0x28: /* ffree sti */
1.1.1.7   root     5886:                 gen_helper_ffree_STN(tcg_const_i32(opreg));
1.1.1.6   root     5887:                 break;
1.1       root     5888:             case 0x2a: /* fst sti */
1.1.1.7   root     5889:                 gen_helper_fmov_STN_ST0(tcg_const_i32(opreg));
1.1       root     5890:                 break;
                   5891:             case 0x2b: /* fstp sti */
                   5892:             case 0x0b: /* fstp1 sti, undocumented op */
                   5893:             case 0x3a: /* fstp8 sti, undocumented op */
                   5894:             case 0x3b: /* fstp9 sti, undocumented op */
1.1.1.7   root     5895:                 gen_helper_fmov_STN_ST0(tcg_const_i32(opreg));
                   5896:                 gen_helper_fpop();
1.1       root     5897:                 break;
                   5898:             case 0x2c: /* fucom st(i) */
1.1.1.7   root     5899:                 gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
                   5900:                 gen_helper_fucom_ST0_FT0();
1.1       root     5901:                 break;
                   5902:             case 0x2d: /* fucomp st(i) */
1.1.1.7   root     5903:                 gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
                   5904:                 gen_helper_fucom_ST0_FT0();
                   5905:                 gen_helper_fpop();
1.1       root     5906:                 break;
                   5907:             case 0x33: /* de/3 */
                   5908:                 switch(rm) {
                   5909:                 case 1: /* fcompp */
1.1.1.7   root     5910:                     gen_helper_fmov_FT0_STN(tcg_const_i32(1));
                   5911:                     gen_helper_fcom_ST0_FT0();
                   5912:                     gen_helper_fpop();
                   5913:                     gen_helper_fpop();
1.1       root     5914:                     break;
                   5915:                 default:
                   5916:                     goto illegal_op;
                   5917:                 }
                   5918:                 break;
                   5919:             case 0x38: /* ffreep sti, undocumented op */
1.1.1.7   root     5920:                 gen_helper_ffree_STN(tcg_const_i32(opreg));
                   5921:                 gen_helper_fpop();
1.1       root     5922:                 break;
                   5923:             case 0x3c: /* df/4 */
                   5924:                 switch(rm) {
                   5925:                 case 0:
1.1.1.7   root     5926:                     gen_helper_fnstsw(cpu_tmp2_i32);
                   5927:                     tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
                   5928:                     gen_op_mov_reg_T0(OT_WORD, R_EAX);
1.1       root     5929:                     break;
                   5930:                 default:
                   5931:                     goto illegal_op;
                   5932:                 }
                   5933:                 break;
                   5934:             case 0x3d: /* fucomip */
                   5935:                 if (s->cc_op != CC_OP_DYNAMIC)
                   5936:                     gen_op_set_cc_op(s->cc_op);
1.1.1.7   root     5937:                 gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
                   5938:                 gen_helper_fucomi_ST0_FT0();
                   5939:                 gen_helper_fpop();
1.1       root     5940:                 s->cc_op = CC_OP_EFLAGS;
                   5941:                 break;
                   5942:             case 0x3e: /* fcomip */
                   5943:                 if (s->cc_op != CC_OP_DYNAMIC)
                   5944:                     gen_op_set_cc_op(s->cc_op);
1.1.1.7   root     5945:                 gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
                   5946:                 gen_helper_fcomi_ST0_FT0();
                   5947:                 gen_helper_fpop();
1.1       root     5948:                 s->cc_op = CC_OP_EFLAGS;
                   5949:                 break;
                   5950:             case 0x10 ... 0x13: /* fcmovxx */
                   5951:             case 0x18 ... 0x1b:
                   5952:                 {
1.1.1.7   root     5953:                     int op1, l1;
                   5954:                     static const uint8_t fcmov_cc[8] = {
1.1       root     5955:                         (JCC_B << 1),
                   5956:                         (JCC_Z << 1),
                   5957:                         (JCC_BE << 1),
                   5958:                         (JCC_P << 1),
                   5959:                     };
1.1.1.7   root     5960:                     op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
                   5961:                     l1 = gen_new_label();
                   5962:                     gen_jcc1(s, s->cc_op, op1, l1);
                   5963:                     gen_helper_fmov_ST0_STN(tcg_const_i32(opreg));
                   5964:                     gen_set_label(l1);
1.1       root     5965:                 }
                   5966:                 break;
                   5967:             default:
                   5968:                 goto illegal_op;
                   5969:             }
                   5970:         }
                   5971:         break;
                   5972:         /************************/
                   5973:         /* string ops */
                   5974: 
                   5975:     case 0xa4: /* movsS */
                   5976:     case 0xa5:
                   5977:         if ((b & 1) == 0)
                   5978:             ot = OT_BYTE;
                   5979:         else
                   5980:             ot = dflag + OT_WORD;
                   5981: 
                   5982:         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
                   5983:             gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
                   5984:         } else {
                   5985:             gen_movs(s, ot);
                   5986:         }
                   5987:         break;
1.1.1.6   root     5988: 
1.1       root     5989:     case 0xaa: /* stosS */
                   5990:     case 0xab:
                   5991:         if ((b & 1) == 0)
                   5992:             ot = OT_BYTE;
                   5993:         else
                   5994:             ot = dflag + OT_WORD;
                   5995: 
                   5996:         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
                   5997:             gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
                   5998:         } else {
                   5999:             gen_stos(s, ot);
                   6000:         }
                   6001:         break;
                   6002:     case 0xac: /* lodsS */
                   6003:     case 0xad:
                   6004:         if ((b & 1) == 0)
                   6005:             ot = OT_BYTE;
                   6006:         else
                   6007:             ot = dflag + OT_WORD;
                   6008:         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
                   6009:             gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
                   6010:         } else {
                   6011:             gen_lods(s, ot);
                   6012:         }
                   6013:         break;
                   6014:     case 0xae: /* scasS */
                   6015:     case 0xaf:
                   6016:         if ((b & 1) == 0)
                   6017:             ot = OT_BYTE;
                   6018:         else
                   6019:             ot = dflag + OT_WORD;
                   6020:         if (prefixes & PREFIX_REPNZ) {
                   6021:             gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
                   6022:         } else if (prefixes & PREFIX_REPZ) {
                   6023:             gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
                   6024:         } else {
                   6025:             gen_scas(s, ot);
                   6026:             s->cc_op = CC_OP_SUBB + ot;
                   6027:         }
                   6028:         break;
                   6029: 
                   6030:     case 0xa6: /* cmpsS */
                   6031:     case 0xa7:
                   6032:         if ((b & 1) == 0)
                   6033:             ot = OT_BYTE;
                   6034:         else
                   6035:             ot = dflag + OT_WORD;
                   6036:         if (prefixes & PREFIX_REPNZ) {
                   6037:             gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
                   6038:         } else if (prefixes & PREFIX_REPZ) {
                   6039:             gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
                   6040:         } else {
                   6041:             gen_cmps(s, ot);
                   6042:             s->cc_op = CC_OP_SUBB + ot;
                   6043:         }
                   6044:         break;
                   6045:     case 0x6c: /* insS */
                   6046:     case 0x6d:
                   6047:         if ((b & 1) == 0)
                   6048:             ot = OT_BYTE;
                   6049:         else
                   6050:             ot = dflag ? OT_LONG : OT_WORD;
1.1.1.7   root     6051:         gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
1.1.1.6   root     6052:         gen_op_andl_T0_ffff();
1.1.1.7   root     6053:         gen_check_io(s, ot, pc_start - s->cs_base, 
                   6054:                      SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
1.1       root     6055:         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
                   6056:             gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
                   6057:         } else {
                   6058:             gen_ins(s, ot);
1.1.1.7   root     6059:             if (use_icount) {
                   6060:                 gen_jmp(s, s->pc - s->cs_base);
                   6061:             }
1.1       root     6062:         }
                   6063:         break;
                   6064:     case 0x6e: /* outsS */
                   6065:     case 0x6f:
                   6066:         if ((b & 1) == 0)
                   6067:             ot = OT_BYTE;
                   6068:         else
                   6069:             ot = dflag ? OT_LONG : OT_WORD;
1.1.1.7   root     6070:         gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
1.1.1.6   root     6071:         gen_op_andl_T0_ffff();
1.1.1.7   root     6072:         gen_check_io(s, ot, pc_start - s->cs_base,
                   6073:                      svm_is_rep(prefixes) | 4);
1.1       root     6074:         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
                   6075:             gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
                   6076:         } else {
                   6077:             gen_outs(s, ot);
1.1.1.7   root     6078:             if (use_icount) {
                   6079:                 gen_jmp(s, s->pc - s->cs_base);
                   6080:             }
1.1       root     6081:         }
                   6082:         break;
                   6083: 
                   6084:         /************************/
                   6085:         /* port I/O */
1.1.1.6   root     6086: 
1.1       root     6087:     case 0xe4:
                   6088:     case 0xe5:
                   6089:         if ((b & 1) == 0)
                   6090:             ot = OT_BYTE;
                   6091:         else
                   6092:             ot = dflag ? OT_LONG : OT_WORD;
                   6093:         val = ldub_code(s->pc++);
                   6094:         gen_op_movl_T0_im(val);
1.1.1.7   root     6095:         gen_check_io(s, ot, pc_start - s->cs_base,
                   6096:                      SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
                   6097:         if (use_icount)
                   6098:             gen_io_start();
                   6099:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   6100:         gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
                   6101:         gen_op_mov_reg_T1(ot, R_EAX);
                   6102:         if (use_icount) {
                   6103:             gen_io_end();
                   6104:             gen_jmp(s, s->pc - s->cs_base);
                   6105:         }
1.1       root     6106:         break;
                   6107:     case 0xe6:
                   6108:     case 0xe7:
                   6109:         if ((b & 1) == 0)
                   6110:             ot = OT_BYTE;
                   6111:         else
                   6112:             ot = dflag ? OT_LONG : OT_WORD;
                   6113:         val = ldub_code(s->pc++);
                   6114:         gen_op_movl_T0_im(val);
1.1.1.7   root     6115:         gen_check_io(s, ot, pc_start - s->cs_base,
                   6116:                      svm_is_rep(prefixes));
                   6117:         gen_op_mov_TN_reg(ot, 1, R_EAX);
                   6118: 
                   6119:         if (use_icount)
                   6120:             gen_io_start();
                   6121:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   6122:         tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
                   6123:         gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
                   6124:         if (use_icount) {
                   6125:             gen_io_end();
                   6126:             gen_jmp(s, s->pc - s->cs_base);
                   6127:         }
1.1       root     6128:         break;
                   6129:     case 0xec:
                   6130:     case 0xed:
                   6131:         if ((b & 1) == 0)
                   6132:             ot = OT_BYTE;
                   6133:         else
                   6134:             ot = dflag ? OT_LONG : OT_WORD;
1.1.1.7   root     6135:         gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
1.1       root     6136:         gen_op_andl_T0_ffff();
1.1.1.7   root     6137:         gen_check_io(s, ot, pc_start - s->cs_base,
                   6138:                      SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
                   6139:         if (use_icount)
                   6140:             gen_io_start();
                   6141:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   6142:         gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
                   6143:         gen_op_mov_reg_T1(ot, R_EAX);
                   6144:         if (use_icount) {
                   6145:             gen_io_end();
                   6146:             gen_jmp(s, s->pc - s->cs_base);
                   6147:         }
1.1       root     6148:         break;
                   6149:     case 0xee:
                   6150:     case 0xef:
                   6151:         if ((b & 1) == 0)
                   6152:             ot = OT_BYTE;
                   6153:         else
                   6154:             ot = dflag ? OT_LONG : OT_WORD;
1.1.1.7   root     6155:         gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
1.1       root     6156:         gen_op_andl_T0_ffff();
1.1.1.7   root     6157:         gen_check_io(s, ot, pc_start - s->cs_base,
                   6158:                      svm_is_rep(prefixes));
                   6159:         gen_op_mov_TN_reg(ot, 1, R_EAX);
                   6160: 
                   6161:         if (use_icount)
                   6162:             gen_io_start();
                   6163:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   6164:         tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
                   6165:         gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
                   6166:         if (use_icount) {
                   6167:             gen_io_end();
                   6168:             gen_jmp(s, s->pc - s->cs_base);
                   6169:         }
1.1       root     6170:         break;
                   6171: 
                   6172:         /************************/
                   6173:         /* control */
                   6174:     case 0xc2: /* ret im */
                   6175:         val = ldsw_code(s->pc);
                   6176:         s->pc += 2;
                   6177:         gen_pop_T0(s);
                   6178:         if (CODE64(s) && s->dflag)
                   6179:             s->dflag = 2;
                   6180:         gen_stack_update(s, val + (2 << s->dflag));
                   6181:         if (s->dflag == 0)
                   6182:             gen_op_andl_T0_ffff();
                   6183:         gen_op_jmp_T0();
                   6184:         gen_eob(s);
                   6185:         break;
                   6186:     case 0xc3: /* ret */
                   6187:         gen_pop_T0(s);
                   6188:         gen_pop_update(s);
                   6189:         if (s->dflag == 0)
                   6190:             gen_op_andl_T0_ffff();
                   6191:         gen_op_jmp_T0();
                   6192:         gen_eob(s);
                   6193:         break;
                   6194:     case 0xca: /* lret im */
                   6195:         val = ldsw_code(s->pc);
                   6196:         s->pc += 2;
                   6197:     do_lret:
                   6198:         if (s->pe && !s->vm86) {
                   6199:             if (s->cc_op != CC_OP_DYNAMIC)
                   6200:                 gen_op_set_cc_op(s->cc_op);
                   6201:             gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     6202:             gen_helper_lret_protected(tcg_const_i32(s->dflag),
                   6203:                                       tcg_const_i32(val));
1.1       root     6204:         } else {
                   6205:             gen_stack_A0(s);
                   6206:             /* pop offset */
1.1.1.7   root     6207:             gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
1.1       root     6208:             if (s->dflag == 0)
                   6209:                 gen_op_andl_T0_ffff();
                   6210:             /* NOTE: keeping EIP updated is not a problem in case of
                   6211:                exception */
                   6212:             gen_op_jmp_T0();
                   6213:             /* pop selector */
                   6214:             gen_op_addl_A0_im(2 << s->dflag);
1.1.1.7   root     6215:             gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
                   6216:             gen_op_movl_seg_T0_vm(R_CS);
1.1       root     6217:             /* add stack offset */
                   6218:             gen_stack_update(s, val + (4 << s->dflag));
                   6219:         }
                   6220:         gen_eob(s);
                   6221:         break;
                   6222:     case 0xcb: /* lret */
                   6223:         val = 0;
                   6224:         goto do_lret;
                   6225:     case 0xcf: /* iret */
1.1.1.7   root     6226:         gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
1.1       root     6227:         if (!s->pe) {
                   6228:             /* real mode */
1.1.1.7   root     6229:             gen_helper_iret_real(tcg_const_i32(s->dflag));
1.1       root     6230:             s->cc_op = CC_OP_EFLAGS;
                   6231:         } else if (s->vm86) {
                   6232:             if (s->iopl != 3) {
                   6233:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   6234:             } else {
1.1.1.7   root     6235:                 gen_helper_iret_real(tcg_const_i32(s->dflag));
1.1       root     6236:                 s->cc_op = CC_OP_EFLAGS;
                   6237:             }
                   6238:         } else {
                   6239:             if (s->cc_op != CC_OP_DYNAMIC)
                   6240:                 gen_op_set_cc_op(s->cc_op);
                   6241:             gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     6242:             gen_helper_iret_protected(tcg_const_i32(s->dflag), 
                   6243:                                       tcg_const_i32(s->pc - s->cs_base));
1.1       root     6244:             s->cc_op = CC_OP_EFLAGS;
                   6245:         }
                   6246:         gen_eob(s);
                   6247:         break;
                   6248:     case 0xe8: /* call im */
                   6249:         {
                   6250:             if (dflag)
                   6251:                 tval = (int32_t)insn_get(s, OT_LONG);
                   6252:             else
                   6253:                 tval = (int16_t)insn_get(s, OT_WORD);
                   6254:             next_eip = s->pc - s->cs_base;
                   6255:             tval += next_eip;
                   6256:             if (s->dflag == 0)
                   6257:                 tval &= 0xffff;
1.1.1.10  root     6258:             else if(!CODE64(s))
                   6259:                 tval &= 0xffffffff;
1.1       root     6260:             gen_movtl_T0_im(next_eip);
                   6261:             gen_push_T0(s);
                   6262:             gen_jmp(s, tval);
                   6263:         }
                   6264:         break;
                   6265:     case 0x9a: /* lcall im */
                   6266:         {
                   6267:             unsigned int selector, offset;
1.1.1.6   root     6268: 
1.1       root     6269:             if (CODE64(s))
                   6270:                 goto illegal_op;
                   6271:             ot = dflag ? OT_LONG : OT_WORD;
                   6272:             offset = insn_get(s, ot);
                   6273:             selector = insn_get(s, OT_WORD);
1.1.1.6   root     6274: 
1.1       root     6275:             gen_op_movl_T0_im(selector);
                   6276:             gen_op_movl_T1_imu(offset);
                   6277:         }
                   6278:         goto do_lcall;
                   6279:     case 0xe9: /* jmp im */
                   6280:         if (dflag)
                   6281:             tval = (int32_t)insn_get(s, OT_LONG);
                   6282:         else
                   6283:             tval = (int16_t)insn_get(s, OT_WORD);
                   6284:         tval += s->pc - s->cs_base;
                   6285:         if (s->dflag == 0)
                   6286:             tval &= 0xffff;
1.1.1.7   root     6287:         else if(!CODE64(s))
                   6288:             tval &= 0xffffffff;
1.1       root     6289:         gen_jmp(s, tval);
                   6290:         break;
                   6291:     case 0xea: /* ljmp im */
                   6292:         {
                   6293:             unsigned int selector, offset;
                   6294: 
                   6295:             if (CODE64(s))
                   6296:                 goto illegal_op;
                   6297:             ot = dflag ? OT_LONG : OT_WORD;
                   6298:             offset = insn_get(s, ot);
                   6299:             selector = insn_get(s, OT_WORD);
1.1.1.6   root     6300: 
1.1       root     6301:             gen_op_movl_T0_im(selector);
                   6302:             gen_op_movl_T1_imu(offset);
                   6303:         }
                   6304:         goto do_ljmp;
                   6305:     case 0xeb: /* jmp Jb */
                   6306:         tval = (int8_t)insn_get(s, OT_BYTE);
                   6307:         tval += s->pc - s->cs_base;
                   6308:         if (s->dflag == 0)
                   6309:             tval &= 0xffff;
                   6310:         gen_jmp(s, tval);
                   6311:         break;
                   6312:     case 0x70 ... 0x7f: /* jcc Jb */
                   6313:         tval = (int8_t)insn_get(s, OT_BYTE);
                   6314:         goto do_jcc;
                   6315:     case 0x180 ... 0x18f: /* jcc Jv */
                   6316:         if (dflag) {
                   6317:             tval = (int32_t)insn_get(s, OT_LONG);
                   6318:         } else {
1.1.1.6   root     6319:             tval = (int16_t)insn_get(s, OT_WORD);
1.1       root     6320:         }
                   6321:     do_jcc:
                   6322:         next_eip = s->pc - s->cs_base;
                   6323:         tval += next_eip;
                   6324:         if (s->dflag == 0)
                   6325:             tval &= 0xffff;
                   6326:         gen_jcc(s, b, tval, next_eip);
                   6327:         break;
                   6328: 
                   6329:     case 0x190 ... 0x19f: /* setcc Gv */
                   6330:         modrm = ldub_code(s->pc++);
                   6331:         gen_setcc(s, b);
                   6332:         gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
                   6333:         break;
                   6334:     case 0x140 ... 0x14f: /* cmov Gv, Ev */
1.1.1.7   root     6335:         {
                   6336:             int l1;
                   6337:             TCGv t0;
                   6338: 
                   6339:             ot = dflag + OT_WORD;
                   6340:             modrm = ldub_code(s->pc++);
                   6341:             reg = ((modrm >> 3) & 7) | rex_r;
                   6342:             mod = (modrm >> 6) & 3;
                   6343:             t0 = tcg_temp_local_new();
                   6344:             if (mod != 3) {
                   6345:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   6346:                 gen_op_ld_v(ot + s->mem_index, t0, cpu_A0);
                   6347:             } else {
                   6348:                 rm = (modrm & 7) | REX_B(s);
                   6349:                 gen_op_mov_v_reg(ot, t0, rm);
                   6350:             }
                   6351: #ifdef TARGET_X86_64
                   6352:             if (ot == OT_LONG) {
                   6353:                 /* XXX: specific Intel behaviour ? */
                   6354:                 l1 = gen_new_label();
                   6355:                 gen_jcc1(s, s->cc_op, b ^ 1, l1);
1.1.1.9   root     6356:                 tcg_gen_mov_tl(cpu_regs[reg], t0);
1.1.1.7   root     6357:                 gen_set_label(l1);
1.1.1.9   root     6358:                 tcg_gen_ext32u_tl(cpu_regs[reg], cpu_regs[reg]);
1.1.1.7   root     6359:             } else
                   6360: #endif
                   6361:             {
                   6362:                 l1 = gen_new_label();
                   6363:                 gen_jcc1(s, s->cc_op, b ^ 1, l1);
                   6364:                 gen_op_mov_reg_v(ot, reg, t0);
                   6365:                 gen_set_label(l1);
                   6366:             }
                   6367:             tcg_temp_free(t0);
1.1       root     6368:         }
                   6369:         break;
1.1.1.6   root     6370: 
1.1       root     6371:         /************************/
                   6372:         /* flags */
                   6373:     case 0x9c: /* pushf */
1.1.1.7   root     6374:         gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
1.1       root     6375:         if (s->vm86 && s->iopl != 3) {
                   6376:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   6377:         } else {
                   6378:             if (s->cc_op != CC_OP_DYNAMIC)
                   6379:                 gen_op_set_cc_op(s->cc_op);
1.1.1.7   root     6380:             gen_helper_read_eflags(cpu_T[0]);
1.1       root     6381:             gen_push_T0(s);
                   6382:         }
                   6383:         break;
                   6384:     case 0x9d: /* popf */
1.1.1.7   root     6385:         gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
1.1       root     6386:         if (s->vm86 && s->iopl != 3) {
                   6387:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   6388:         } else {
                   6389:             gen_pop_T0(s);
                   6390:             if (s->cpl == 0) {
                   6391:                 if (s->dflag) {
1.1.1.7   root     6392:                     gen_helper_write_eflags(cpu_T[0],
                   6393:                                        tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK)));
1.1       root     6394:                 } else {
1.1.1.7   root     6395:                     gen_helper_write_eflags(cpu_T[0],
                   6396:                                        tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff));
1.1       root     6397:                 }
                   6398:             } else {
                   6399:                 if (s->cpl <= s->iopl) {
                   6400:                     if (s->dflag) {
1.1.1.7   root     6401:                         gen_helper_write_eflags(cpu_T[0],
                   6402:                                            tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK)));
1.1       root     6403:                     } else {
1.1.1.7   root     6404:                         gen_helper_write_eflags(cpu_T[0],
                   6405:                                            tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff));
1.1       root     6406:                     }
                   6407:                 } else {
                   6408:                     if (s->dflag) {
1.1.1.7   root     6409:                         gen_helper_write_eflags(cpu_T[0],
                   6410:                                            tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK)));
1.1       root     6411:                     } else {
1.1.1.7   root     6412:                         gen_helper_write_eflags(cpu_T[0],
                   6413:                                            tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff));
1.1       root     6414:                     }
                   6415:                 }
                   6416:             }
                   6417:             gen_pop_update(s);
                   6418:             s->cc_op = CC_OP_EFLAGS;
                   6419:             /* abort translation because TF flag may change */
                   6420:             gen_jmp_im(s->pc - s->cs_base);
                   6421:             gen_eob(s);
                   6422:         }
                   6423:         break;
                   6424:     case 0x9e: /* sahf */
1.1.1.7   root     6425:         if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
1.1       root     6426:             goto illegal_op;
1.1.1.7   root     6427:         gen_op_mov_TN_reg(OT_BYTE, 0, R_AH);
1.1       root     6428:         if (s->cc_op != CC_OP_DYNAMIC)
                   6429:             gen_op_set_cc_op(s->cc_op);
1.1.1.7   root     6430:         gen_compute_eflags(cpu_cc_src);
                   6431:         tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
                   6432:         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], CC_S | CC_Z | CC_A | CC_P | CC_C);
                   6433:         tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T[0]);
1.1       root     6434:         s->cc_op = CC_OP_EFLAGS;
                   6435:         break;
                   6436:     case 0x9f: /* lahf */
1.1.1.7   root     6437:         if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
1.1       root     6438:             goto illegal_op;
                   6439:         if (s->cc_op != CC_OP_DYNAMIC)
                   6440:             gen_op_set_cc_op(s->cc_op);
1.1.1.7   root     6441:         gen_compute_eflags(cpu_T[0]);
                   6442:         /* Note: gen_compute_eflags() only gives the condition codes */
                   6443:         tcg_gen_ori_tl(cpu_T[0], cpu_T[0], 0x02);
                   6444:         gen_op_mov_reg_T0(OT_BYTE, R_AH);
1.1       root     6445:         break;
                   6446:     case 0xf5: /* cmc */
                   6447:         if (s->cc_op != CC_OP_DYNAMIC)
                   6448:             gen_op_set_cc_op(s->cc_op);
1.1.1.7   root     6449:         gen_compute_eflags(cpu_cc_src);
                   6450:         tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
1.1       root     6451:         s->cc_op = CC_OP_EFLAGS;
                   6452:         break;
                   6453:     case 0xf8: /* clc */
                   6454:         if (s->cc_op != CC_OP_DYNAMIC)
                   6455:             gen_op_set_cc_op(s->cc_op);
1.1.1.7   root     6456:         gen_compute_eflags(cpu_cc_src);
                   6457:         tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
1.1       root     6458:         s->cc_op = CC_OP_EFLAGS;
                   6459:         break;
                   6460:     case 0xf9: /* stc */
                   6461:         if (s->cc_op != CC_OP_DYNAMIC)
                   6462:             gen_op_set_cc_op(s->cc_op);
1.1.1.7   root     6463:         gen_compute_eflags(cpu_cc_src);
                   6464:         tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
1.1       root     6465:         s->cc_op = CC_OP_EFLAGS;
                   6466:         break;
                   6467:     case 0xfc: /* cld */
1.1.1.7   root     6468:         tcg_gen_movi_i32(cpu_tmp2_i32, 1);
                   6469:         tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUState, df));
1.1       root     6470:         break;
                   6471:     case 0xfd: /* std */
1.1.1.7   root     6472:         tcg_gen_movi_i32(cpu_tmp2_i32, -1);
                   6473:         tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUState, df));
1.1       root     6474:         break;
                   6475: 
                   6476:         /************************/
                   6477:         /* bit operations */
                   6478:     case 0x1ba: /* bt/bts/btr/btc Gv, im */
                   6479:         ot = dflag + OT_WORD;
                   6480:         modrm = ldub_code(s->pc++);
1.1.1.3   root     6481:         op = (modrm >> 3) & 7;
1.1       root     6482:         mod = (modrm >> 6) & 3;
                   6483:         rm = (modrm & 7) | REX_B(s);
                   6484:         if (mod != 3) {
                   6485:             s->rip_offset = 1;
                   6486:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     6487:             gen_op_ld_T0_A0(ot + s->mem_index);
1.1       root     6488:         } else {
1.1.1.7   root     6489:             gen_op_mov_TN_reg(ot, 0, rm);
1.1       root     6490:         }
                   6491:         /* load shift */
                   6492:         val = ldub_code(s->pc++);
                   6493:         gen_op_movl_T1_im(val);
                   6494:         if (op < 4)
                   6495:             goto illegal_op;
                   6496:         op -= 4;
1.1.1.7   root     6497:         goto bt_op;
1.1       root     6498:     case 0x1a3: /* bt Gv, Ev */
                   6499:         op = 0;
                   6500:         goto do_btx;
                   6501:     case 0x1ab: /* bts */
                   6502:         op = 1;
                   6503:         goto do_btx;
                   6504:     case 0x1b3: /* btr */
                   6505:         op = 2;
                   6506:         goto do_btx;
                   6507:     case 0x1bb: /* btc */
                   6508:         op = 3;
                   6509:     do_btx:
                   6510:         ot = dflag + OT_WORD;
                   6511:         modrm = ldub_code(s->pc++);
                   6512:         reg = ((modrm >> 3) & 7) | rex_r;
                   6513:         mod = (modrm >> 6) & 3;
                   6514:         rm = (modrm & 7) | REX_B(s);
1.1.1.7   root     6515:         gen_op_mov_TN_reg(OT_LONG, 1, reg);
1.1       root     6516:         if (mod != 3) {
                   6517:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   6518:             /* specific case: we need to add a displacement */
1.1.1.7   root     6519:             gen_exts(ot, cpu_T[1]);
                   6520:             tcg_gen_sari_tl(cpu_tmp0, cpu_T[1], 3 + ot);
                   6521:             tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
                   6522:             tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
                   6523:             gen_op_ld_T0_A0(ot + s->mem_index);
1.1       root     6524:         } else {
1.1.1.7   root     6525:             gen_op_mov_TN_reg(ot, 0, rm);
                   6526:         }
                   6527:     bt_op:
                   6528:         tcg_gen_andi_tl(cpu_T[1], cpu_T[1], (1 << (3 + ot)) - 1);
                   6529:         switch(op) {
                   6530:         case 0:
                   6531:             tcg_gen_shr_tl(cpu_cc_src, cpu_T[0], cpu_T[1]);
                   6532:             tcg_gen_movi_tl(cpu_cc_dst, 0);
                   6533:             break;
                   6534:         case 1:
                   6535:             tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
                   6536:             tcg_gen_movi_tl(cpu_tmp0, 1);
                   6537:             tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
                   6538:             tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
                   6539:             break;
                   6540:         case 2:
                   6541:             tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
                   6542:             tcg_gen_movi_tl(cpu_tmp0, 1);
                   6543:             tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
                   6544:             tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
                   6545:             tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
                   6546:             break;
                   6547:         default:
                   6548:         case 3:
                   6549:             tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
                   6550:             tcg_gen_movi_tl(cpu_tmp0, 1);
                   6551:             tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
                   6552:             tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
                   6553:             break;
1.1       root     6554:         }
                   6555:         s->cc_op = CC_OP_SARB + ot;
                   6556:         if (op != 0) {
                   6557:             if (mod != 3)
1.1.1.7   root     6558:                 gen_op_st_T0_A0(ot + s->mem_index);
1.1       root     6559:             else
1.1.1.7   root     6560:                 gen_op_mov_reg_T0(ot, rm);
                   6561:             tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
                   6562:             tcg_gen_movi_tl(cpu_cc_dst, 0);
1.1       root     6563:         }
                   6564:         break;
                   6565:     case 0x1bc: /* bsf */
                   6566:     case 0x1bd: /* bsr */
1.1.1.7   root     6567:         {
                   6568:             int label1;
                   6569:             TCGv t0;
                   6570: 
                   6571:             ot = dflag + OT_WORD;
                   6572:             modrm = ldub_code(s->pc++);
                   6573:             reg = ((modrm >> 3) & 7) | rex_r;
1.1.1.9   root     6574:             gen_ldst_modrm(s,modrm, ot, OR_TMP0, 0);
1.1.1.7   root     6575:             gen_extu(ot, cpu_T[0]);
                   6576:             t0 = tcg_temp_local_new();
                   6577:             tcg_gen_mov_tl(t0, cpu_T[0]);
1.1.1.9   root     6578:             if ((b & 1) && (prefixes & PREFIX_REPZ) &&
                   6579:                 (s->cpuid_ext3_features & CPUID_EXT3_ABM)) {
                   6580:                 switch(ot) {
                   6581:                 case OT_WORD: gen_helper_lzcnt(cpu_T[0], t0,
                   6582:                     tcg_const_i32(16)); break;
                   6583:                 case OT_LONG: gen_helper_lzcnt(cpu_T[0], t0,
                   6584:                     tcg_const_i32(32)); break;
                   6585:                 case OT_QUAD: gen_helper_lzcnt(cpu_T[0], t0,
                   6586:                     tcg_const_i32(64)); break;
                   6587:                 }
                   6588:                 gen_op_mov_reg_T0(ot, reg);
1.1.1.7   root     6589:             } else {
1.1.1.9   root     6590:                 label1 = gen_new_label();
                   6591:                 tcg_gen_movi_tl(cpu_cc_dst, 0);
                   6592:                 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, label1);
                   6593:                 if (b & 1) {
                   6594:                     gen_helper_bsr(cpu_T[0], t0);
                   6595:                 } else {
                   6596:                     gen_helper_bsf(cpu_T[0], t0);
                   6597:                 }
                   6598:                 gen_op_mov_reg_T0(ot, reg);
                   6599:                 tcg_gen_movi_tl(cpu_cc_dst, 1);
                   6600:                 gen_set_label(label1);
                   6601:                 tcg_gen_discard_tl(cpu_cc_src);
                   6602:                 s->cc_op = CC_OP_LOGICB + ot;
1.1.1.7   root     6603:             }
                   6604:             tcg_temp_free(t0);
                   6605:         }
1.1       root     6606:         break;
                   6607:         /************************/
                   6608:         /* bcd */
                   6609:     case 0x27: /* daa */
                   6610:         if (CODE64(s))
                   6611:             goto illegal_op;
                   6612:         if (s->cc_op != CC_OP_DYNAMIC)
                   6613:             gen_op_set_cc_op(s->cc_op);
1.1.1.7   root     6614:         gen_helper_daa();
1.1       root     6615:         s->cc_op = CC_OP_EFLAGS;
                   6616:         break;
                   6617:     case 0x2f: /* das */
                   6618:         if (CODE64(s))
                   6619:             goto illegal_op;
                   6620:         if (s->cc_op != CC_OP_DYNAMIC)
                   6621:             gen_op_set_cc_op(s->cc_op);
1.1.1.7   root     6622:         gen_helper_das();
1.1       root     6623:         s->cc_op = CC_OP_EFLAGS;
                   6624:         break;
                   6625:     case 0x37: /* aaa */
                   6626:         if (CODE64(s))
                   6627:             goto illegal_op;
                   6628:         if (s->cc_op != CC_OP_DYNAMIC)
                   6629:             gen_op_set_cc_op(s->cc_op);
1.1.1.7   root     6630:         gen_helper_aaa();
1.1       root     6631:         s->cc_op = CC_OP_EFLAGS;
                   6632:         break;
                   6633:     case 0x3f: /* aas */
                   6634:         if (CODE64(s))
                   6635:             goto illegal_op;
                   6636:         if (s->cc_op != CC_OP_DYNAMIC)
                   6637:             gen_op_set_cc_op(s->cc_op);
1.1.1.7   root     6638:         gen_helper_aas();
1.1       root     6639:         s->cc_op = CC_OP_EFLAGS;
                   6640:         break;
                   6641:     case 0xd4: /* aam */
                   6642:         if (CODE64(s))
                   6643:             goto illegal_op;
                   6644:         val = ldub_code(s->pc++);
1.1.1.6   root     6645:         if (val == 0) {
                   6646:             gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
                   6647:         } else {
1.1.1.7   root     6648:             gen_helper_aam(tcg_const_i32(val));
1.1.1.6   root     6649:             s->cc_op = CC_OP_LOGICB;
                   6650:         }
1.1       root     6651:         break;
                   6652:     case 0xd5: /* aad */
                   6653:         if (CODE64(s))
                   6654:             goto illegal_op;
                   6655:         val = ldub_code(s->pc++);
1.1.1.7   root     6656:         gen_helper_aad(tcg_const_i32(val));
1.1       root     6657:         s->cc_op = CC_OP_LOGICB;
                   6658:         break;
                   6659:         /************************/
                   6660:         /* misc */
                   6661:     case 0x90: /* nop */
                   6662:         /* XXX: correct lock test for all insn */
1.1.1.12  root     6663:         if (prefixes & PREFIX_LOCK) {
1.1       root     6664:             goto illegal_op;
1.1.1.12  root     6665:         }
                   6666:         /* If REX_B is set, then this is xchg eax, r8d, not a nop.  */
                   6667:         if (REX_B(s)) {
                   6668:             goto do_xchg_reg_eax;
                   6669:         }
1.1.1.6   root     6670:         if (prefixes & PREFIX_REPZ) {
                   6671:             gen_svm_check_intercept(s, pc_start, SVM_EXIT_PAUSE);
                   6672:         }
1.1       root     6673:         break;
                   6674:     case 0x9b: /* fwait */
1.1.1.6   root     6675:         if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
1.1       root     6676:             (HF_MP_MASK | HF_TS_MASK)) {
                   6677:             gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
                   6678:         } else {
                   6679:             if (s->cc_op != CC_OP_DYNAMIC)
                   6680:                 gen_op_set_cc_op(s->cc_op);
                   6681:             gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     6682:             gen_helper_fwait();
1.1       root     6683:         }
                   6684:         break;
                   6685:     case 0xcc: /* int3 */
                   6686:         gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
                   6687:         break;
                   6688:     case 0xcd: /* int N */
                   6689:         val = ldub_code(s->pc++);
                   6690:         if (s->vm86 && s->iopl != 3) {
1.1.1.6   root     6691:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
1.1       root     6692:         } else {
                   6693:             gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
                   6694:         }
                   6695:         break;
                   6696:     case 0xce: /* into */
                   6697:         if (CODE64(s))
                   6698:             goto illegal_op;
                   6699:         if (s->cc_op != CC_OP_DYNAMIC)
                   6700:             gen_op_set_cc_op(s->cc_op);
                   6701:         gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     6702:         gen_helper_into(tcg_const_i32(s->pc - pc_start));
1.1       root     6703:         break;
1.1.1.7   root     6704: #ifdef WANT_ICEBP
1.1       root     6705:     case 0xf1: /* icebp (undocumented, exits to external debugger) */
1.1.1.7   root     6706:         gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
1.1       root     6707: #if 1
                   6708:         gen_debug(s, pc_start - s->cs_base);
                   6709: #else
                   6710:         /* start debug */
                   6711:         tb_flush(cpu_single_env);
                   6712:         cpu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
                   6713: #endif
                   6714:         break;
1.1.1.7   root     6715: #endif
1.1       root     6716:     case 0xfa: /* cli */
                   6717:         if (!s->vm86) {
                   6718:             if (s->cpl <= s->iopl) {
1.1.1.7   root     6719:                 gen_helper_cli();
1.1       root     6720:             } else {
                   6721:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   6722:             }
                   6723:         } else {
                   6724:             if (s->iopl == 3) {
1.1.1.7   root     6725:                 gen_helper_cli();
1.1       root     6726:             } else {
                   6727:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   6728:             }
                   6729:         }
                   6730:         break;
                   6731:     case 0xfb: /* sti */
                   6732:         if (!s->vm86) {
                   6733:             if (s->cpl <= s->iopl) {
                   6734:             gen_sti:
1.1.1.7   root     6735:                 gen_helper_sti();
1.1       root     6736:                 /* interruptions are enabled only the first insn after sti */
                   6737:                 /* If several instructions disable interrupts, only the
                   6738:                    _first_ does it */
                   6739:                 if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
1.1.1.7   root     6740:                     gen_helper_set_inhibit_irq();
1.1       root     6741:                 /* give a chance to handle pending irqs */
                   6742:                 gen_jmp_im(s->pc - s->cs_base);
                   6743:                 gen_eob(s);
                   6744:             } else {
                   6745:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   6746:             }
                   6747:         } else {
                   6748:             if (s->iopl == 3) {
                   6749:                 goto gen_sti;
                   6750:             } else {
                   6751:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   6752:             }
                   6753:         }
                   6754:         break;
                   6755:     case 0x62: /* bound */
                   6756:         if (CODE64(s))
                   6757:             goto illegal_op;
                   6758:         ot = dflag ? OT_LONG : OT_WORD;
                   6759:         modrm = ldub_code(s->pc++);
                   6760:         reg = (modrm >> 3) & 7;
                   6761:         mod = (modrm >> 6) & 3;
                   6762:         if (mod == 3)
                   6763:             goto illegal_op;
1.1.1.7   root     6764:         gen_op_mov_TN_reg(ot, 0, reg);
1.1       root     6765:         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   6766:         gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     6767:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
1.1       root     6768:         if (ot == OT_WORD)
1.1.1.7   root     6769:             gen_helper_boundw(cpu_A0, cpu_tmp2_i32);
1.1       root     6770:         else
1.1.1.7   root     6771:             gen_helper_boundl(cpu_A0, cpu_tmp2_i32);
1.1       root     6772:         break;
                   6773:     case 0x1c8 ... 0x1cf: /* bswap reg */
                   6774:         reg = (b & 7) | REX_B(s);
                   6775: #ifdef TARGET_X86_64
                   6776:         if (dflag == 2) {
1.1.1.7   root     6777:             gen_op_mov_TN_reg(OT_QUAD, 0, reg);
1.1.1.8   root     6778:             tcg_gen_bswap64_i64(cpu_T[0], cpu_T[0]);
1.1.1.7   root     6779:             gen_op_mov_reg_T0(OT_QUAD, reg);
1.1.1.6   root     6780:         } else
1.1.1.8   root     6781: #endif
1.1.1.7   root     6782:         {
                   6783:             gen_op_mov_TN_reg(OT_LONG, 0, reg);
1.1.1.8   root     6784:             tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
                   6785:             tcg_gen_bswap32_tl(cpu_T[0], cpu_T[0]);
1.1.1.7   root     6786:             gen_op_mov_reg_T0(OT_LONG, reg);
1.1       root     6787:         }
                   6788:         break;
                   6789:     case 0xd6: /* salc */
                   6790:         if (CODE64(s))
                   6791:             goto illegal_op;
                   6792:         if (s->cc_op != CC_OP_DYNAMIC)
                   6793:             gen_op_set_cc_op(s->cc_op);
1.1.1.7   root     6794:         gen_compute_eflags_c(cpu_T[0]);
                   6795:         tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
                   6796:         gen_op_mov_reg_T0(OT_BYTE, R_EAX);
1.1       root     6797:         break;
                   6798:     case 0xe0: /* loopnz */
                   6799:     case 0xe1: /* loopz */
                   6800:     case 0xe2: /* loop */
                   6801:     case 0xe3: /* jecxz */
                   6802:         {
1.1.1.7   root     6803:             int l1, l2, l3;
1.1       root     6804: 
                   6805:             tval = (int8_t)insn_get(s, OT_BYTE);
                   6806:             next_eip = s->pc - s->cs_base;
                   6807:             tval += next_eip;
                   6808:             if (s->dflag == 0)
                   6809:                 tval &= 0xffff;
1.1.1.6   root     6810: 
1.1       root     6811:             l1 = gen_new_label();
                   6812:             l2 = gen_new_label();
1.1.1.7   root     6813:             l3 = gen_new_label();
1.1       root     6814:             b &= 3;
1.1.1.7   root     6815:             switch(b) {
                   6816:             case 0: /* loopnz */
                   6817:             case 1: /* loopz */
                   6818:                 if (s->cc_op != CC_OP_DYNAMIC)
                   6819:                     gen_op_set_cc_op(s->cc_op);
                   6820:                 gen_op_add_reg_im(s->aflag, R_ECX, -1);
                   6821:                 gen_op_jz_ecx(s->aflag, l3);
                   6822:                 gen_compute_eflags(cpu_tmp0);
                   6823:                 tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_Z);
                   6824:                 if (b == 0) {
                   6825:                     tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
                   6826:                 } else {
                   6827:                     tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, l1);
                   6828:                 }
                   6829:                 break;
                   6830:             case 2: /* loop */
                   6831:                 gen_op_add_reg_im(s->aflag, R_ECX, -1);
                   6832:                 gen_op_jnz_ecx(s->aflag, l1);
                   6833:                 break;
                   6834:             default:
                   6835:             case 3: /* jcxz */
                   6836:                 gen_op_jz_ecx(s->aflag, l1);
                   6837:                 break;
1.1       root     6838:             }
                   6839: 
1.1.1.7   root     6840:             gen_set_label(l3);
1.1       root     6841:             gen_jmp_im(next_eip);
1.1.1.7   root     6842:             tcg_gen_br(l2);
                   6843: 
1.1       root     6844:             gen_set_label(l1);
                   6845:             gen_jmp_im(tval);
                   6846:             gen_set_label(l2);
                   6847:             gen_eob(s);
                   6848:         }
                   6849:         break;
                   6850:     case 0x130: /* wrmsr */
                   6851:     case 0x132: /* rdmsr */
                   6852:         if (s->cpl != 0) {
                   6853:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   6854:         } else {
1.1.1.7   root     6855:             if (s->cc_op != CC_OP_DYNAMIC)
                   6856:                 gen_op_set_cc_op(s->cc_op);
                   6857:             gen_jmp_im(pc_start - s->cs_base);
1.1.1.6   root     6858:             if (b & 2) {
1.1.1.7   root     6859:                 gen_helper_rdmsr();
1.1.1.6   root     6860:             } else {
1.1.1.7   root     6861:                 gen_helper_wrmsr();
1.1.1.6   root     6862:             }
1.1       root     6863:         }
                   6864:         break;
                   6865:     case 0x131: /* rdtsc */
1.1.1.7   root     6866:         if (s->cc_op != CC_OP_DYNAMIC)
                   6867:             gen_op_set_cc_op(s->cc_op);
1.1       root     6868:         gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     6869:         if (use_icount)
                   6870:             gen_io_start();
                   6871:         gen_helper_rdtsc();
                   6872:         if (use_icount) {
                   6873:             gen_io_end();
                   6874:             gen_jmp(s, s->pc - s->cs_base);
                   6875:         }
1.1       root     6876:         break;
1.1.1.6   root     6877:     case 0x133: /* rdpmc */
1.1.1.7   root     6878:         if (s->cc_op != CC_OP_DYNAMIC)
                   6879:             gen_op_set_cc_op(s->cc_op);
1.1.1.6   root     6880:         gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     6881:         gen_helper_rdpmc();
1.1.1.6   root     6882:         break;
1.1       root     6883:     case 0x134: /* sysenter */
1.1.1.7   root     6884:         /* For Intel SYSENTER is valid on 64-bit */
                   6885:         if (CODE64(s) && cpu_single_env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
1.1       root     6886:             goto illegal_op;
                   6887:         if (!s->pe) {
                   6888:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   6889:         } else {
1.1.1.13  root     6890:             gen_update_cc_op(s);
1.1       root     6891:             gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     6892:             gen_helper_sysenter();
1.1       root     6893:             gen_eob(s);
                   6894:         }
                   6895:         break;
                   6896:     case 0x135: /* sysexit */
1.1.1.7   root     6897:         /* For Intel SYSEXIT is valid on 64-bit */
                   6898:         if (CODE64(s) && cpu_single_env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
1.1       root     6899:             goto illegal_op;
                   6900:         if (!s->pe) {
                   6901:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   6902:         } else {
1.1.1.13  root     6903:             gen_update_cc_op(s);
1.1       root     6904:             gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     6905:             gen_helper_sysexit(tcg_const_i32(dflag));
1.1       root     6906:             gen_eob(s);
                   6907:         }
                   6908:         break;
                   6909: #ifdef TARGET_X86_64
                   6910:     case 0x105: /* syscall */
                   6911:         /* XXX: is it usable in real mode ? */
1.1.1.13  root     6912:         gen_update_cc_op(s);
1.1       root     6913:         gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     6914:         gen_helper_syscall(tcg_const_i32(s->pc - pc_start));
1.1       root     6915:         gen_eob(s);
                   6916:         break;
                   6917:     case 0x107: /* sysret */
                   6918:         if (!s->pe) {
                   6919:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   6920:         } else {
1.1.1.13  root     6921:             gen_update_cc_op(s);
1.1       root     6922:             gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     6923:             gen_helper_sysret(tcg_const_i32(s->dflag));
1.1       root     6924:             /* condition codes are modified only in long mode */
                   6925:             if (s->lma)
                   6926:                 s->cc_op = CC_OP_EFLAGS;
                   6927:             gen_eob(s);
                   6928:         }
                   6929:         break;
                   6930: #endif
                   6931:     case 0x1a2: /* cpuid */
1.1.1.7   root     6932:         if (s->cc_op != CC_OP_DYNAMIC)
                   6933:             gen_op_set_cc_op(s->cc_op);
                   6934:         gen_jmp_im(pc_start - s->cs_base);
                   6935:         gen_helper_cpuid();
1.1       root     6936:         break;
                   6937:     case 0xf4: /* hlt */
                   6938:         if (s->cpl != 0) {
                   6939:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   6940:         } else {
                   6941:             if (s->cc_op != CC_OP_DYNAMIC)
                   6942:                 gen_op_set_cc_op(s->cc_op);
1.1.1.7   root     6943:             gen_jmp_im(pc_start - s->cs_base);
                   6944:             gen_helper_hlt(tcg_const_i32(s->pc - pc_start));
1.1.1.13  root     6945:             s->is_jmp = DISAS_TB_JUMP;
1.1       root     6946:         }
                   6947:         break;
                   6948:     case 0x100:
                   6949:         modrm = ldub_code(s->pc++);
                   6950:         mod = (modrm >> 6) & 3;
                   6951:         op = (modrm >> 3) & 7;
                   6952:         switch(op) {
                   6953:         case 0: /* sldt */
                   6954:             if (!s->pe || s->vm86)
                   6955:                 goto illegal_op;
1.1.1.7   root     6956:             gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
                   6957:             tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,ldt.selector));
1.1       root     6958:             ot = OT_WORD;
                   6959:             if (mod == 3)
                   6960:                 ot += s->dflag;
                   6961:             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
                   6962:             break;
                   6963:         case 2: /* lldt */
                   6964:             if (!s->pe || s->vm86)
                   6965:                 goto illegal_op;
                   6966:             if (s->cpl != 0) {
                   6967:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   6968:             } else {
1.1.1.7   root     6969:                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
1.1       root     6970:                 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
                   6971:                 gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     6972:                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   6973:                 gen_helper_lldt(cpu_tmp2_i32);
1.1       root     6974:             }
                   6975:             break;
                   6976:         case 1: /* str */
                   6977:             if (!s->pe || s->vm86)
                   6978:                 goto illegal_op;
1.1.1.7   root     6979:             gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
                   6980:             tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,tr.selector));
1.1       root     6981:             ot = OT_WORD;
                   6982:             if (mod == 3)
                   6983:                 ot += s->dflag;
                   6984:             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
                   6985:             break;
                   6986:         case 3: /* ltr */
                   6987:             if (!s->pe || s->vm86)
                   6988:                 goto illegal_op;
                   6989:             if (s->cpl != 0) {
                   6990:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   6991:             } else {
1.1.1.7   root     6992:                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
1.1       root     6993:                 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
                   6994:                 gen_jmp_im(pc_start - s->cs_base);
1.1.1.7   root     6995:                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
                   6996:                 gen_helper_ltr(cpu_tmp2_i32);
1.1       root     6997:             }
                   6998:             break;
                   6999:         case 4: /* verr */
                   7000:         case 5: /* verw */
                   7001:             if (!s->pe || s->vm86)
                   7002:                 goto illegal_op;
                   7003:             gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
                   7004:             if (s->cc_op != CC_OP_DYNAMIC)
                   7005:                 gen_op_set_cc_op(s->cc_op);
                   7006:             if (op == 4)
1.1.1.7   root     7007:                 gen_helper_verr(cpu_T[0]);
1.1       root     7008:             else
1.1.1.7   root     7009:                 gen_helper_verw(cpu_T[0]);
1.1       root     7010:             s->cc_op = CC_OP_EFLAGS;
                   7011:             break;
                   7012:         default:
                   7013:             goto illegal_op;
                   7014:         }
                   7015:         break;
                   7016:     case 0x101:
                   7017:         modrm = ldub_code(s->pc++);
                   7018:         mod = (modrm >> 6) & 3;
                   7019:         op = (modrm >> 3) & 7;
1.1.1.4   root     7020:         rm = modrm & 7;
1.1       root     7021:         switch(op) {
                   7022:         case 0: /* sgdt */
                   7023:             if (mod == 3)
                   7024:                 goto illegal_op;
1.1.1.7   root     7025:             gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ);
1.1       root     7026:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     7027:             tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.limit));
                   7028:             gen_op_st_T0_A0(OT_WORD + s->mem_index);
1.1       root     7029:             gen_add_A0_im(s, 2);
1.1.1.7   root     7030:             tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.base));
1.1       root     7031:             if (!s->dflag)
                   7032:                 gen_op_andl_T0_im(0xffffff);
1.1.1.7   root     7033:             gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
1.1       root     7034:             break;
1.1.1.4   root     7035:         case 1:
                   7036:             if (mod == 3) {
                   7037:                 switch (rm) {
                   7038:                 case 0: /* monitor */
                   7039:                     if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
                   7040:                         s->cpl != 0)
                   7041:                         goto illegal_op;
1.1.1.7   root     7042:                     if (s->cc_op != CC_OP_DYNAMIC)
                   7043:                         gen_op_set_cc_op(s->cc_op);
1.1.1.4   root     7044:                     gen_jmp_im(pc_start - s->cs_base);
                   7045: #ifdef TARGET_X86_64
                   7046:                     if (s->aflag == 2) {
1.1.1.7   root     7047:                         gen_op_movq_A0_reg(R_EAX);
1.1.1.6   root     7048:                     } else
1.1.1.4   root     7049: #endif
                   7050:                     {
1.1.1.7   root     7051:                         gen_op_movl_A0_reg(R_EAX);
1.1.1.4   root     7052:                         if (s->aflag == 0)
                   7053:                             gen_op_andl_A0_ffff();
                   7054:                     }
                   7055:                     gen_add_A0_ds_seg(s);
1.1.1.7   root     7056:                     gen_helper_monitor(cpu_A0);
1.1.1.4   root     7057:                     break;
                   7058:                 case 1: /* mwait */
                   7059:                     if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
                   7060:                         s->cpl != 0)
                   7061:                         goto illegal_op;
1.1.1.13  root     7062:                     gen_update_cc_op(s);
1.1.1.7   root     7063:                     gen_jmp_im(pc_start - s->cs_base);
                   7064:                     gen_helper_mwait(tcg_const_i32(s->pc - pc_start));
1.1.1.4   root     7065:                     gen_eob(s);
                   7066:                     break;
                   7067:                 default:
                   7068:                     goto illegal_op;
                   7069:                 }
                   7070:             } else { /* sidt */
1.1.1.7   root     7071:                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ);
1.1.1.4   root     7072:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     7073:                 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.limit));
                   7074:                 gen_op_st_T0_A0(OT_WORD + s->mem_index);
1.1.1.4   root     7075:                 gen_add_A0_im(s, 2);
1.1.1.7   root     7076:                 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.base));
1.1.1.4   root     7077:                 if (!s->dflag)
                   7078:                     gen_op_andl_T0_im(0xffffff);
1.1.1.7   root     7079:                 gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
1.1.1.4   root     7080:             }
                   7081:             break;
1.1       root     7082:         case 2: /* lgdt */
                   7083:         case 3: /* lidt */
1.1.1.6   root     7084:             if (mod == 3) {
1.1.1.7   root     7085:                 if (s->cc_op != CC_OP_DYNAMIC)
                   7086:                     gen_op_set_cc_op(s->cc_op);
                   7087:                 gen_jmp_im(pc_start - s->cs_base);
1.1.1.6   root     7088:                 switch(rm) {
                   7089:                 case 0: /* VMRUN */
1.1.1.7   root     7090:                     if (!(s->flags & HF_SVME_MASK) || !s->pe)
                   7091:                         goto illegal_op;
                   7092:                     if (s->cpl != 0) {
                   7093:                         gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
1.1.1.6   root     7094:                         break;
1.1.1.7   root     7095:                     } else {
                   7096:                         gen_helper_vmrun(tcg_const_i32(s->aflag),
                   7097:                                          tcg_const_i32(s->pc - pc_start));
                   7098:                         tcg_gen_exit_tb(0);
1.1.1.13  root     7099:                         s->is_jmp = DISAS_TB_JUMP;
1.1.1.7   root     7100:                     }
1.1.1.6   root     7101:                     break;
                   7102:                 case 1: /* VMMCALL */
1.1.1.7   root     7103:                     if (!(s->flags & HF_SVME_MASK))
                   7104:                         goto illegal_op;
                   7105:                     gen_helper_vmmcall();
1.1.1.6   root     7106:                     break;
                   7107:                 case 2: /* VMLOAD */
1.1.1.7   root     7108:                     if (!(s->flags & HF_SVME_MASK) || !s->pe)
                   7109:                         goto illegal_op;
                   7110:                     if (s->cpl != 0) {
                   7111:                         gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   7112:                         break;
                   7113:                     } else {
                   7114:                         gen_helper_vmload(tcg_const_i32(s->aflag));
                   7115:                     }
1.1.1.6   root     7116:                     break;
                   7117:                 case 3: /* VMSAVE */
1.1.1.7   root     7118:                     if (!(s->flags & HF_SVME_MASK) || !s->pe)
                   7119:                         goto illegal_op;
                   7120:                     if (s->cpl != 0) {
                   7121:                         gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   7122:                         break;
                   7123:                     } else {
                   7124:                         gen_helper_vmsave(tcg_const_i32(s->aflag));
                   7125:                     }
1.1.1.6   root     7126:                     break;
                   7127:                 case 4: /* STGI */
1.1.1.7   root     7128:                     if ((!(s->flags & HF_SVME_MASK) &&
                   7129:                          !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) || 
                   7130:                         !s->pe)
                   7131:                         goto illegal_op;
                   7132:                     if (s->cpl != 0) {
                   7133:                         gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   7134:                         break;
                   7135:                     } else {
                   7136:                         gen_helper_stgi();
                   7137:                     }
1.1.1.6   root     7138:                     break;
                   7139:                 case 5: /* CLGI */
1.1.1.7   root     7140:                     if (!(s->flags & HF_SVME_MASK) || !s->pe)
                   7141:                         goto illegal_op;
                   7142:                     if (s->cpl != 0) {
                   7143:                         gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   7144:                         break;
                   7145:                     } else {
                   7146:                         gen_helper_clgi();
                   7147:                     }
1.1.1.6   root     7148:                     break;
                   7149:                 case 6: /* SKINIT */
1.1.1.7   root     7150:                     if ((!(s->flags & HF_SVME_MASK) && 
                   7151:                          !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) || 
                   7152:                         !s->pe)
                   7153:                         goto illegal_op;
                   7154:                     gen_helper_skinit();
1.1.1.6   root     7155:                     break;
                   7156:                 case 7: /* INVLPGA */
1.1.1.7   root     7157:                     if (!(s->flags & HF_SVME_MASK) || !s->pe)
                   7158:                         goto illegal_op;
                   7159:                     if (s->cpl != 0) {
                   7160:                         gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   7161:                         break;
                   7162:                     } else {
                   7163:                         gen_helper_invlpga(tcg_const_i32(s->aflag));
                   7164:                     }
1.1.1.6   root     7165:                     break;
                   7166:                 default:
                   7167:                     goto illegal_op;
                   7168:                 }
                   7169:             } else if (s->cpl != 0) {
1.1       root     7170:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   7171:             } else {
1.1.1.7   root     7172:                 gen_svm_check_intercept(s, pc_start,
                   7173:                                         op==2 ? SVM_EXIT_GDTR_WRITE : SVM_EXIT_IDTR_WRITE);
1.1       root     7174:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     7175:                 gen_op_ld_T1_A0(OT_WORD + s->mem_index);
1.1       root     7176:                 gen_add_A0_im(s, 2);
1.1.1.7   root     7177:                 gen_op_ld_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
1.1       root     7178:                 if (!s->dflag)
                   7179:                     gen_op_andl_T0_im(0xffffff);
                   7180:                 if (op == 2) {
1.1.1.7   root     7181:                     tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,gdt.base));
                   7182:                     tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,gdt.limit));
1.1       root     7183:                 } else {
1.1.1.7   root     7184:                     tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,idt.base));
                   7185:                     tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,idt.limit));
1.1       root     7186:                 }
                   7187:             }
                   7188:             break;
                   7189:         case 4: /* smsw */
1.1.1.7   root     7190:             gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
1.1.1.9   root     7191: #if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
1.1.1.7   root     7192:             tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]) + 4);
                   7193: #else
                   7194:             tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]));
                   7195: #endif
1.1       root     7196:             gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 1);
                   7197:             break;
                   7198:         case 6: /* lmsw */
                   7199:             if (s->cpl != 0) {
                   7200:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   7201:             } else {
1.1.1.7   root     7202:                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
1.1       root     7203:                 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
1.1.1.7   root     7204:                 gen_helper_lmsw(cpu_T[0]);
1.1       root     7205:                 gen_jmp_im(s->pc - s->cs_base);
                   7206:                 gen_eob(s);
                   7207:             }
                   7208:             break;
1.1.1.9   root     7209:         case 7:
                   7210:             if (mod != 3) { /* invlpg */
                   7211:                 if (s->cpl != 0) {
                   7212:                     gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   7213:                 } else {
                   7214:                     if (s->cc_op != CC_OP_DYNAMIC)
                   7215:                         gen_op_set_cc_op(s->cc_op);
                   7216:                     gen_jmp_im(pc_start - s->cs_base);
                   7217:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   7218:                     gen_helper_invlpg(cpu_A0);
                   7219:                     gen_jmp_im(s->pc - s->cs_base);
                   7220:                     gen_eob(s);
                   7221:                 }
1.1       root     7222:             } else {
1.1.1.9   root     7223:                 switch (rm) {
                   7224:                 case 0: /* swapgs */
1.1       root     7225: #ifdef TARGET_X86_64
1.1.1.9   root     7226:                     if (CODE64(s)) {
                   7227:                         if (s->cpl != 0) {
                   7228:                             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   7229:                         } else {
                   7230:                             tcg_gen_ld_tl(cpu_T[0], cpu_env,
                   7231:                                 offsetof(CPUX86State,segs[R_GS].base));
                   7232:                             tcg_gen_ld_tl(cpu_T[1], cpu_env,
                   7233:                                 offsetof(CPUX86State,kernelgsbase));
                   7234:                             tcg_gen_st_tl(cpu_T[1], cpu_env,
                   7235:                                 offsetof(CPUX86State,segs[R_GS].base));
                   7236:                             tcg_gen_st_tl(cpu_T[0], cpu_env,
                   7237:                                 offsetof(CPUX86State,kernelgsbase));
                   7238:                         }
1.1.1.6   root     7239:                     } else
1.1       root     7240: #endif
                   7241:                     {
                   7242:                         goto illegal_op;
                   7243:                     }
1.1.1.9   root     7244:                     break;
                   7245:                 case 1: /* rdtscp */
                   7246:                     if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP))
                   7247:                         goto illegal_op;
1.1.1.7   root     7248:                     if (s->cc_op != CC_OP_DYNAMIC)
                   7249:                         gen_op_set_cc_op(s->cc_op);
                   7250:                     gen_jmp_im(pc_start - s->cs_base);
1.1.1.9   root     7251:                     if (use_icount)
                   7252:                         gen_io_start();
                   7253:                     gen_helper_rdtscp();
                   7254:                     if (use_icount) {
                   7255:                         gen_io_end();
                   7256:                         gen_jmp(s, s->pc - s->cs_base);
                   7257:                     }
                   7258:                     break;
                   7259:                 default:
                   7260:                     goto illegal_op;
1.1       root     7261:                 }
                   7262:             }
                   7263:             break;
                   7264:         default:
                   7265:             goto illegal_op;
                   7266:         }
                   7267:         break;
                   7268:     case 0x108: /* invd */
                   7269:     case 0x109: /* wbinvd */
                   7270:         if (s->cpl != 0) {
                   7271:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   7272:         } else {
1.1.1.7   root     7273:             gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
1.1       root     7274:             /* nothing to do */
                   7275:         }
                   7276:         break;
                   7277:     case 0x63: /* arpl or movslS (x86_64) */
                   7278: #ifdef TARGET_X86_64
                   7279:         if (CODE64(s)) {
                   7280:             int d_ot;
                   7281:             /* d_ot is the size of destination */
                   7282:             d_ot = dflag + OT_WORD;
                   7283: 
                   7284:             modrm = ldub_code(s->pc++);
                   7285:             reg = ((modrm >> 3) & 7) | rex_r;
                   7286:             mod = (modrm >> 6) & 3;
                   7287:             rm = (modrm & 7) | REX_B(s);
1.1.1.6   root     7288: 
1.1       root     7289:             if (mod == 3) {
1.1.1.7   root     7290:                 gen_op_mov_TN_reg(OT_LONG, 0, rm);
1.1       root     7291:                 /* sign extend */
                   7292:                 if (d_ot == OT_QUAD)
1.1.1.7   root     7293:                     tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
                   7294:                 gen_op_mov_reg_T0(d_ot, reg);
1.1       root     7295:             } else {
                   7296:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   7297:                 if (d_ot == OT_QUAD) {
1.1.1.7   root     7298:                     gen_op_lds_T0_A0(OT_LONG + s->mem_index);
1.1       root     7299:                 } else {
1.1.1.7   root     7300:                     gen_op_ld_T0_A0(OT_LONG + s->mem_index);
1.1       root     7301:                 }
1.1.1.7   root     7302:                 gen_op_mov_reg_T0(d_ot, reg);
1.1       root     7303:             }
1.1.1.6   root     7304:         } else
1.1       root     7305: #endif
                   7306:         {
1.1.1.7   root     7307:             int label1;
1.1.1.9   root     7308:             TCGv t0, t1, t2, a0;
1.1.1.7   root     7309: 
1.1       root     7310:             if (!s->pe || s->vm86)
                   7311:                 goto illegal_op;
1.1.1.7   root     7312:             t0 = tcg_temp_local_new();
                   7313:             t1 = tcg_temp_local_new();
                   7314:             t2 = tcg_temp_local_new();
                   7315:             ot = OT_WORD;
1.1       root     7316:             modrm = ldub_code(s->pc++);
                   7317:             reg = (modrm >> 3) & 7;
                   7318:             mod = (modrm >> 6) & 3;
                   7319:             rm = modrm & 7;
                   7320:             if (mod != 3) {
                   7321:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     7322:                 gen_op_ld_v(ot + s->mem_index, t0, cpu_A0);
1.1.1.9   root     7323:                 a0 = tcg_temp_local_new();
                   7324:                 tcg_gen_mov_tl(a0, cpu_A0);
1.1       root     7325:             } else {
1.1.1.7   root     7326:                 gen_op_mov_v_reg(ot, t0, rm);
1.1.1.9   root     7327:                 TCGV_UNUSED(a0);
1.1       root     7328:             }
1.1.1.7   root     7329:             gen_op_mov_v_reg(ot, t1, reg);
                   7330:             tcg_gen_andi_tl(cpu_tmp0, t0, 3);
                   7331:             tcg_gen_andi_tl(t1, t1, 3);
                   7332:             tcg_gen_movi_tl(t2, 0);
                   7333:             label1 = gen_new_label();
                   7334:             tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, t1, label1);
                   7335:             tcg_gen_andi_tl(t0, t0, ~3);
                   7336:             tcg_gen_or_tl(t0, t0, t1);
                   7337:             tcg_gen_movi_tl(t2, CC_Z);
                   7338:             gen_set_label(label1);
1.1       root     7339:             if (mod != 3) {
1.1.1.9   root     7340:                 gen_op_st_v(ot + s->mem_index, t0, a0);
                   7341:                 tcg_temp_free(a0);
                   7342:            } else {
1.1.1.7   root     7343:                 gen_op_mov_reg_v(ot, rm, t0);
1.1       root     7344:             }
1.1.1.7   root     7345:             if (s->cc_op != CC_OP_DYNAMIC)
                   7346:                 gen_op_set_cc_op(s->cc_op);
                   7347:             gen_compute_eflags(cpu_cc_src);
                   7348:             tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
                   7349:             tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
                   7350:             s->cc_op = CC_OP_EFLAGS;
                   7351:             tcg_temp_free(t0);
                   7352:             tcg_temp_free(t1);
                   7353:             tcg_temp_free(t2);
1.1       root     7354:         }
                   7355:         break;
                   7356:     case 0x102: /* lar */
                   7357:     case 0x103: /* lsl */
1.1.1.7   root     7358:         {
                   7359:             int label1;
                   7360:             TCGv t0;
                   7361:             if (!s->pe || s->vm86)
                   7362:                 goto illegal_op;
                   7363:             ot = dflag ? OT_LONG : OT_WORD;
                   7364:             modrm = ldub_code(s->pc++);
                   7365:             reg = ((modrm >> 3) & 7) | rex_r;
                   7366:             gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
                   7367:             t0 = tcg_temp_local_new();
                   7368:             if (s->cc_op != CC_OP_DYNAMIC)
                   7369:                 gen_op_set_cc_op(s->cc_op);
                   7370:             if (b == 0x102)
                   7371:                 gen_helper_lar(t0, cpu_T[0]);
                   7372:             else
                   7373:                 gen_helper_lsl(t0, cpu_T[0]);
                   7374:             tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
                   7375:             label1 = gen_new_label();
                   7376:             tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
                   7377:             gen_op_mov_reg_v(ot, reg, t0);
                   7378:             gen_set_label(label1);
                   7379:             s->cc_op = CC_OP_EFLAGS;
                   7380:             tcg_temp_free(t0);
                   7381:         }
1.1       root     7382:         break;
                   7383:     case 0x118:
                   7384:         modrm = ldub_code(s->pc++);
                   7385:         mod = (modrm >> 6) & 3;
                   7386:         op = (modrm >> 3) & 7;
                   7387:         switch(op) {
                   7388:         case 0: /* prefetchnta */
                   7389:         case 1: /* prefetchnt0 */
                   7390:         case 2: /* prefetchnt0 */
                   7391:         case 3: /* prefetchnt0 */
                   7392:             if (mod == 3)
                   7393:                 goto illegal_op;
                   7394:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   7395:             /* nothing more to do */
                   7396:             break;
1.1.1.5   root     7397:         default: /* nop (multi byte) */
                   7398:             gen_nop_modrm(s, modrm);
                   7399:             break;
1.1       root     7400:         }
                   7401:         break;
1.1.1.5   root     7402:     case 0x119 ... 0x11f: /* nop (multi byte) */
                   7403:         modrm = ldub_code(s->pc++);
                   7404:         gen_nop_modrm(s, modrm);
                   7405:         break;
1.1       root     7406:     case 0x120: /* mov reg, crN */
                   7407:     case 0x122: /* mov crN, reg */
                   7408:         if (s->cpl != 0) {
                   7409:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   7410:         } else {
                   7411:             modrm = ldub_code(s->pc++);
                   7412:             if ((modrm & 0xc0) != 0xc0)
                   7413:                 goto illegal_op;
                   7414:             rm = (modrm & 7) | REX_B(s);
                   7415:             reg = ((modrm >> 3) & 7) | rex_r;
                   7416:             if (CODE64(s))
                   7417:                 ot = OT_QUAD;
                   7418:             else
                   7419:                 ot = OT_LONG;
1.1.1.9   root     7420:             if ((prefixes & PREFIX_LOCK) && (reg == 0) &&
                   7421:                 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
                   7422:                 reg = 8;
                   7423:             }
1.1       root     7424:             switch(reg) {
                   7425:             case 0:
                   7426:             case 2:
                   7427:             case 3:
                   7428:             case 4:
                   7429:             case 8:
1.1.1.7   root     7430:                 if (s->cc_op != CC_OP_DYNAMIC)
                   7431:                     gen_op_set_cc_op(s->cc_op);
                   7432:                 gen_jmp_im(pc_start - s->cs_base);
1.1       root     7433:                 if (b & 2) {
1.1.1.7   root     7434:                     gen_op_mov_TN_reg(ot, 0, rm);
                   7435:                     gen_helper_write_crN(tcg_const_i32(reg), cpu_T[0]);
1.1       root     7436:                     gen_jmp_im(s->pc - s->cs_base);
                   7437:                     gen_eob(s);
                   7438:                 } else {
1.1.1.7   root     7439:                     gen_helper_read_crN(cpu_T[0], tcg_const_i32(reg));
                   7440:                     gen_op_mov_reg_T0(ot, rm);
1.1       root     7441:                 }
                   7442:                 break;
                   7443:             default:
                   7444:                 goto illegal_op;
                   7445:             }
                   7446:         }
                   7447:         break;
                   7448:     case 0x121: /* mov reg, drN */
                   7449:     case 0x123: /* mov drN, reg */
                   7450:         if (s->cpl != 0) {
                   7451:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   7452:         } else {
                   7453:             modrm = ldub_code(s->pc++);
                   7454:             if ((modrm & 0xc0) != 0xc0)
                   7455:                 goto illegal_op;
                   7456:             rm = (modrm & 7) | REX_B(s);
                   7457:             reg = ((modrm >> 3) & 7) | rex_r;
                   7458:             if (CODE64(s))
                   7459:                 ot = OT_QUAD;
                   7460:             else
                   7461:                 ot = OT_LONG;
                   7462:             /* XXX: do it dynamically with CR4.DE bit */
                   7463:             if (reg == 4 || reg == 5 || reg >= 8)
                   7464:                 goto illegal_op;
                   7465:             if (b & 2) {
1.1.1.6   root     7466:                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
1.1.1.7   root     7467:                 gen_op_mov_TN_reg(ot, 0, rm);
                   7468:                 gen_helper_movl_drN_T0(tcg_const_i32(reg), cpu_T[0]);
1.1       root     7469:                 gen_jmp_im(s->pc - s->cs_base);
                   7470:                 gen_eob(s);
                   7471:             } else {
1.1.1.6   root     7472:                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
1.1.1.7   root     7473:                 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,dr[reg]));
                   7474:                 gen_op_mov_reg_T0(ot, rm);
1.1       root     7475:             }
                   7476:         }
                   7477:         break;
                   7478:     case 0x106: /* clts */
                   7479:         if (s->cpl != 0) {
                   7480:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   7481:         } else {
1.1.1.6   root     7482:             gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
1.1.1.7   root     7483:             gen_helper_clts();
1.1       root     7484:             /* abort block because static cpu state changed */
                   7485:             gen_jmp_im(s->pc - s->cs_base);
                   7486:             gen_eob(s);
                   7487:         }
                   7488:         break;
1.1.1.7   root     7489:     /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
1.1       root     7490:     case 0x1c3: /* MOVNTI reg, mem */
                   7491:         if (!(s->cpuid_features & CPUID_SSE2))
                   7492:             goto illegal_op;
                   7493:         ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
                   7494:         modrm = ldub_code(s->pc++);
                   7495:         mod = (modrm >> 6) & 3;
                   7496:         if (mod == 3)
                   7497:             goto illegal_op;
                   7498:         reg = ((modrm >> 3) & 7) | rex_r;
                   7499:         /* generate a generic store */
                   7500:         gen_ldst_modrm(s, modrm, ot, reg, 1);
                   7501:         break;
                   7502:     case 0x1ae:
                   7503:         modrm = ldub_code(s->pc++);
                   7504:         mod = (modrm >> 6) & 3;
                   7505:         op = (modrm >> 3) & 7;
                   7506:         switch(op) {
                   7507:         case 0: /* fxsave */
1.1.1.6   root     7508:             if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
1.1.1.9   root     7509:                 (s->prefix & PREFIX_LOCK))
1.1       root     7510:                 goto illegal_op;
1.1.1.9   root     7511:             if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
1.1.1.3   root     7512:                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
                   7513:                 break;
                   7514:             }
1.1       root     7515:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     7516:             if (s->cc_op != CC_OP_DYNAMIC)
                   7517:                 gen_op_set_cc_op(s->cc_op);
                   7518:             gen_jmp_im(pc_start - s->cs_base);
                   7519:             gen_helper_fxsave(cpu_A0, tcg_const_i32((s->dflag == 2)));
1.1       root     7520:             break;
                   7521:         case 1: /* fxrstor */
1.1.1.6   root     7522:             if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
1.1.1.9   root     7523:                 (s->prefix & PREFIX_LOCK))
1.1       root     7524:                 goto illegal_op;
1.1.1.9   root     7525:             if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
1.1.1.3   root     7526:                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
                   7527:                 break;
                   7528:             }
1.1       root     7529:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1.1.1.7   root     7530:             if (s->cc_op != CC_OP_DYNAMIC)
                   7531:                 gen_op_set_cc_op(s->cc_op);
                   7532:             gen_jmp_im(pc_start - s->cs_base);
                   7533:             gen_helper_fxrstor(cpu_A0, tcg_const_i32((s->dflag == 2)));
1.1       root     7534:             break;
                   7535:         case 2: /* ldmxcsr */
                   7536:         case 3: /* stmxcsr */
                   7537:             if (s->flags & HF_TS_MASK) {
                   7538:                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
                   7539:                 break;
                   7540:             }
                   7541:             if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
                   7542:                 mod == 3)
                   7543:                 goto illegal_op;
                   7544:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   7545:             if (op == 2) {
1.1.1.7   root     7546:                 gen_op_ld_T0_A0(OT_LONG + s->mem_index);
                   7547:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
1.1       root     7548:             } else {
1.1.1.7   root     7549:                 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
                   7550:                 gen_op_st_T0_A0(OT_LONG + s->mem_index);
1.1       root     7551:             }
                   7552:             break;
                   7553:         case 5: /* lfence */
                   7554:         case 6: /* mfence */
1.1.1.15  root     7555:             if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE2))
1.1       root     7556:                 goto illegal_op;
                   7557:             break;
                   7558:         case 7: /* sfence / clflush */
                   7559:             if ((modrm & 0xc7) == 0xc0) {
                   7560:                 /* sfence */
1.1.1.7   root     7561:                 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
1.1       root     7562:                 if (!(s->cpuid_features & CPUID_SSE))
                   7563:                     goto illegal_op;
                   7564:             } else {
                   7565:                 /* clflush */
                   7566:                 if (!(s->cpuid_features & CPUID_CLFLUSH))
                   7567:                     goto illegal_op;
                   7568:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   7569:             }
                   7570:             break;
                   7571:         default:
                   7572:             goto illegal_op;
                   7573:         }
                   7574:         break;
1.1.1.7   root     7575:     case 0x10d: /* 3DNow! prefetch(w) */
1.1       root     7576:         modrm = ldub_code(s->pc++);
1.1.1.7   root     7577:         mod = (modrm >> 6) & 3;
                   7578:         if (mod == 3)
                   7579:             goto illegal_op;
1.1       root     7580:         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   7581:         /* ignore for now */
                   7582:         break;
1.1.1.5   root     7583:     case 0x1aa: /* rsm */
1.1.1.7   root     7584:         gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
1.1.1.5   root     7585:         if (!(s->flags & HF_SMM_MASK))
                   7586:             goto illegal_op;
1.1.1.13  root     7587:         gen_update_cc_op(s);
1.1.1.5   root     7588:         gen_jmp_im(s->pc - s->cs_base);
1.1.1.7   root     7589:         gen_helper_rsm();
1.1.1.5   root     7590:         gen_eob(s);
                   7591:         break;
1.1.1.7   root     7592:     case 0x1b8: /* SSE4.2 popcnt */
                   7593:         if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
                   7594:              PREFIX_REPZ)
                   7595:             goto illegal_op;
                   7596:         if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
                   7597:             goto illegal_op;
                   7598: 
                   7599:         modrm = ldub_code(s->pc++);
                   7600:         reg = ((modrm >> 3) & 7);
                   7601: 
                   7602:         if (s->prefix & PREFIX_DATA)
                   7603:             ot = OT_WORD;
                   7604:         else if (s->dflag != 2)
                   7605:             ot = OT_LONG;
                   7606:         else
                   7607:             ot = OT_QUAD;
                   7608: 
                   7609:         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
                   7610:         gen_helper_popcnt(cpu_T[0], cpu_T[0], tcg_const_i32(ot));
                   7611:         gen_op_mov_reg_T0(ot, reg);
                   7612: 
                   7613:         s->cc_op = CC_OP_EFLAGS;
                   7614:         break;
                   7615:     case 0x10e ... 0x10f:
                   7616:         /* 3DNow! instructions, ignore prefixes */
                   7617:         s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
1.1       root     7618:     case 0x110 ... 0x117:
                   7619:     case 0x128 ... 0x12f:
1.1.1.7   root     7620:     case 0x138 ... 0x13a:
1.1.1.9   root     7621:     case 0x150 ... 0x179:
1.1       root     7622:     case 0x17c ... 0x17f:
                   7623:     case 0x1c2:
                   7624:     case 0x1c4 ... 0x1c6:
                   7625:     case 0x1d0 ... 0x1fe:
                   7626:         gen_sse(s, b, pc_start, rex_r);
                   7627:         break;
                   7628:     default:
                   7629:         goto illegal_op;
                   7630:     }
                   7631:     /* lock generation */
                   7632:     if (s->prefix & PREFIX_LOCK)
1.1.1.7   root     7633:         gen_helper_unlock();
1.1       root     7634:     return s->pc;
                   7635:  illegal_op:
                   7636:     if (s->prefix & PREFIX_LOCK)
1.1.1.7   root     7637:         gen_helper_unlock();
1.1       root     7638:     /* XXX: ensure that no lock was generated */
                   7639:     gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
                   7640:     return s->pc;
                   7641: }
                   7642: 
                   7643: void optimize_flags_init(void)
                   7644: {
1.1.1.7   root     7645:     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
                   7646:     cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0,
                   7647:                                        offsetof(CPUState, cc_op), "cc_op");
                   7648:     cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_src),
                   7649:                                     "cc_src");
                   7650:     cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_dst),
                   7651:                                     "cc_dst");
                   7652:     cpu_cc_tmp = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_tmp),
                   7653:                                     "cc_tmp");
                   7654: 
1.1.1.9   root     7655: #ifdef TARGET_X86_64
                   7656:     cpu_regs[R_EAX] = tcg_global_mem_new_i64(TCG_AREG0,
                   7657:                                              offsetof(CPUState, regs[R_EAX]), "rax");
                   7658:     cpu_regs[R_ECX] = tcg_global_mem_new_i64(TCG_AREG0,
                   7659:                                              offsetof(CPUState, regs[R_ECX]), "rcx");
                   7660:     cpu_regs[R_EDX] = tcg_global_mem_new_i64(TCG_AREG0,
                   7661:                                              offsetof(CPUState, regs[R_EDX]), "rdx");
                   7662:     cpu_regs[R_EBX] = tcg_global_mem_new_i64(TCG_AREG0,
                   7663:                                              offsetof(CPUState, regs[R_EBX]), "rbx");
                   7664:     cpu_regs[R_ESP] = tcg_global_mem_new_i64(TCG_AREG0,
                   7665:                                              offsetof(CPUState, regs[R_ESP]), "rsp");
                   7666:     cpu_regs[R_EBP] = tcg_global_mem_new_i64(TCG_AREG0,
                   7667:                                              offsetof(CPUState, regs[R_EBP]), "rbp");
                   7668:     cpu_regs[R_ESI] = tcg_global_mem_new_i64(TCG_AREG0,
                   7669:                                              offsetof(CPUState, regs[R_ESI]), "rsi");
                   7670:     cpu_regs[R_EDI] = tcg_global_mem_new_i64(TCG_AREG0,
                   7671:                                              offsetof(CPUState, regs[R_EDI]), "rdi");
                   7672:     cpu_regs[8] = tcg_global_mem_new_i64(TCG_AREG0,
                   7673:                                          offsetof(CPUState, regs[8]), "r8");
                   7674:     cpu_regs[9] = tcg_global_mem_new_i64(TCG_AREG0,
                   7675:                                           offsetof(CPUState, regs[9]), "r9");
                   7676:     cpu_regs[10] = tcg_global_mem_new_i64(TCG_AREG0,
                   7677:                                           offsetof(CPUState, regs[10]), "r10");
                   7678:     cpu_regs[11] = tcg_global_mem_new_i64(TCG_AREG0,
                   7679:                                           offsetof(CPUState, regs[11]), "r11");
                   7680:     cpu_regs[12] = tcg_global_mem_new_i64(TCG_AREG0,
                   7681:                                           offsetof(CPUState, regs[12]), "r12");
                   7682:     cpu_regs[13] = tcg_global_mem_new_i64(TCG_AREG0,
                   7683:                                           offsetof(CPUState, regs[13]), "r13");
                   7684:     cpu_regs[14] = tcg_global_mem_new_i64(TCG_AREG0,
                   7685:                                           offsetof(CPUState, regs[14]), "r14");
                   7686:     cpu_regs[15] = tcg_global_mem_new_i64(TCG_AREG0,
                   7687:                                           offsetof(CPUState, regs[15]), "r15");
                   7688: #else
                   7689:     cpu_regs[R_EAX] = tcg_global_mem_new_i32(TCG_AREG0,
                   7690:                                              offsetof(CPUState, regs[R_EAX]), "eax");
                   7691:     cpu_regs[R_ECX] = tcg_global_mem_new_i32(TCG_AREG0,
                   7692:                                              offsetof(CPUState, regs[R_ECX]), "ecx");
                   7693:     cpu_regs[R_EDX] = tcg_global_mem_new_i32(TCG_AREG0,
                   7694:                                              offsetof(CPUState, regs[R_EDX]), "edx");
                   7695:     cpu_regs[R_EBX] = tcg_global_mem_new_i32(TCG_AREG0,
                   7696:                                              offsetof(CPUState, regs[R_EBX]), "ebx");
                   7697:     cpu_regs[R_ESP] = tcg_global_mem_new_i32(TCG_AREG0,
                   7698:                                              offsetof(CPUState, regs[R_ESP]), "esp");
                   7699:     cpu_regs[R_EBP] = tcg_global_mem_new_i32(TCG_AREG0,
                   7700:                                              offsetof(CPUState, regs[R_EBP]), "ebp");
                   7701:     cpu_regs[R_ESI] = tcg_global_mem_new_i32(TCG_AREG0,
                   7702:                                              offsetof(CPUState, regs[R_ESI]), "esi");
                   7703:     cpu_regs[R_EDI] = tcg_global_mem_new_i32(TCG_AREG0,
                   7704:                                              offsetof(CPUState, regs[R_EDI]), "edi");
                   7705: #endif
                   7706: 
1.1.1.7   root     7707:     /* register helpers */
                   7708: #define GEN_HELPER 2
                   7709: #include "helper.h"
1.1       root     7710: }
                   7711: 
                   7712: /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
                   7713:    basic block 'tb'. If search_pc is TRUE, also generate PC
                   7714:    information for each intermediate instruction. */
1.1.1.7   root     7715: static inline void gen_intermediate_code_internal(CPUState *env,
                   7716:                                                   TranslationBlock *tb,
                   7717:                                                   int search_pc)
1.1       root     7718: {
                   7719:     DisasContext dc1, *dc = &dc1;
                   7720:     target_ulong pc_ptr;
                   7721:     uint16_t *gen_opc_end;
1.1.1.7   root     7722:     CPUBreakpoint *bp;
1.1.1.13  root     7723:     int j, lj;
1.1.1.6   root     7724:     uint64_t flags;
1.1       root     7725:     target_ulong pc_start;
                   7726:     target_ulong cs_base;
1.1.1.7   root     7727:     int num_insns;
                   7728:     int max_insns;
1.1.1.6   root     7729: 
1.1       root     7730:     /* generate intermediate code */
                   7731:     pc_start = tb->pc;
                   7732:     cs_base = tb->cs_base;
                   7733:     flags = tb->flags;
                   7734: 
                   7735:     dc->pe = (flags >> HF_PE_SHIFT) & 1;
                   7736:     dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
                   7737:     dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
                   7738:     dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
                   7739:     dc->f_st = 0;
                   7740:     dc->vm86 = (flags >> VM_SHIFT) & 1;
                   7741:     dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
                   7742:     dc->iopl = (flags >> IOPL_SHIFT) & 3;
                   7743:     dc->tf = (flags >> TF_SHIFT) & 1;
                   7744:     dc->singlestep_enabled = env->singlestep_enabled;
                   7745:     dc->cc_op = CC_OP_DYNAMIC;
                   7746:     dc->cs_base = cs_base;
                   7747:     dc->tb = tb;
                   7748:     dc->popl_esp_hack = 0;
                   7749:     /* select memory access functions */
                   7750:     dc->mem_index = 0;
                   7751:     if (flags & HF_SOFTMMU_MASK) {
                   7752:         if (dc->cpl == 3)
                   7753:             dc->mem_index = 2 * 4;
                   7754:         else
                   7755:             dc->mem_index = 1 * 4;
                   7756:     }
                   7757:     dc->cpuid_features = env->cpuid_features;
1.1.1.4   root     7758:     dc->cpuid_ext_features = env->cpuid_ext_features;
1.1.1.7   root     7759:     dc->cpuid_ext2_features = env->cpuid_ext2_features;
                   7760:     dc->cpuid_ext3_features = env->cpuid_ext3_features;
1.1       root     7761: #ifdef TARGET_X86_64
                   7762:     dc->lma = (flags >> HF_LMA_SHIFT) & 1;
                   7763:     dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
                   7764: #endif
                   7765:     dc->flags = flags;
                   7766:     dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
                   7767:                     (flags & HF_INHIBIT_IRQ_MASK)
                   7768: #ifndef CONFIG_SOFTMMU
                   7769:                     || (flags & HF_SOFTMMU_MASK)
                   7770: #endif
                   7771:                     );
                   7772: #if 0
                   7773:     /* check addseg logic */
                   7774:     if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
                   7775:         printf("ERROR addseg\n");
                   7776: #endif
                   7777: 
1.1.1.7   root     7778:     cpu_T[0] = tcg_temp_new();
                   7779:     cpu_T[1] = tcg_temp_new();
                   7780:     cpu_A0 = tcg_temp_new();
                   7781:     cpu_T3 = tcg_temp_new();
                   7782: 
                   7783:     cpu_tmp0 = tcg_temp_new();
                   7784:     cpu_tmp1_i64 = tcg_temp_new_i64();
                   7785:     cpu_tmp2_i32 = tcg_temp_new_i32();
                   7786:     cpu_tmp3_i32 = tcg_temp_new_i32();
                   7787:     cpu_tmp4 = tcg_temp_new();
                   7788:     cpu_tmp5 = tcg_temp_new();
                   7789:     cpu_ptr0 = tcg_temp_new_ptr();
                   7790:     cpu_ptr1 = tcg_temp_new_ptr();
                   7791: 
1.1       root     7792:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
                   7793: 
                   7794:     dc->is_jmp = DISAS_NEXT;
                   7795:     pc_ptr = pc_start;
                   7796:     lj = -1;
1.1.1.7   root     7797:     num_insns = 0;
                   7798:     max_insns = tb->cflags & CF_COUNT_MASK;
                   7799:     if (max_insns == 0)
                   7800:         max_insns = CF_COUNT_MASK;
1.1       root     7801: 
1.1.1.7   root     7802:     gen_icount_start();
1.1       root     7803:     for(;;) {
1.1.1.9   root     7804:         if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
                   7805:             QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
1.1.1.8   root     7806:                 if (bp->pc == pc_ptr &&
                   7807:                     !((bp->flags & BP_CPU) && (tb->flags & HF_RF_MASK))) {
1.1       root     7808:                     gen_debug(dc, pc_ptr - dc->cs_base);
                   7809:                     break;
                   7810:                 }
                   7811:             }
                   7812:         }
                   7813:         if (search_pc) {
                   7814:             j = gen_opc_ptr - gen_opc_buf;
                   7815:             if (lj < j) {
                   7816:                 lj++;
                   7817:                 while (lj < j)
                   7818:                     gen_opc_instr_start[lj++] = 0;
                   7819:             }
                   7820:             gen_opc_pc[lj] = pc_ptr;
                   7821:             gen_opc_cc_op[lj] = dc->cc_op;
                   7822:             gen_opc_instr_start[lj] = 1;
1.1.1.7   root     7823:             gen_opc_icount[lj] = num_insns;
1.1       root     7824:         }
1.1.1.7   root     7825:         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
                   7826:             gen_io_start();
                   7827: 
1.1       root     7828:         pc_ptr = disas_insn(dc, pc_ptr);
1.1.1.7   root     7829:         num_insns++;
1.1       root     7830:         /* stop translation if indicated */
                   7831:         if (dc->is_jmp)
                   7832:             break;
                   7833:         /* if single step mode, we generate only one instruction and
                   7834:            generate an exception */
                   7835:         /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
                   7836:            the flag and abort the translation to give the irqs a
                   7837:            change to be happen */
1.1.1.6   root     7838:         if (dc->tf || dc->singlestep_enabled ||
1.1.1.7   root     7839:             (flags & HF_INHIBIT_IRQ_MASK)) {
1.1       root     7840:             gen_jmp_im(pc_ptr - dc->cs_base);
                   7841:             gen_eob(dc);
                   7842:             break;
                   7843:         }
                   7844:         /* if too long translation, stop generation too */
                   7845:         if (gen_opc_ptr >= gen_opc_end ||
1.1.1.7   root     7846:             (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32) ||
                   7847:             num_insns >= max_insns) {
1.1       root     7848:             gen_jmp_im(pc_ptr - dc->cs_base);
                   7849:             gen_eob(dc);
                   7850:             break;
                   7851:         }
1.1.1.8   root     7852:         if (singlestep) {
                   7853:             gen_jmp_im(pc_ptr - dc->cs_base);
                   7854:             gen_eob(dc);
                   7855:             break;
                   7856:         }
1.1       root     7857:     }
1.1.1.7   root     7858:     if (tb->cflags & CF_LAST_IO)
                   7859:         gen_io_end();
                   7860:     gen_icount_end(tb, num_insns);
1.1       root     7861:     *gen_opc_ptr = INDEX_op_end;
                   7862:     /* we don't forget to fill the last values */
                   7863:     if (search_pc) {
                   7864:         j = gen_opc_ptr - gen_opc_buf;
                   7865:         lj++;
                   7866:         while (lj <= j)
                   7867:             gen_opc_instr_start[lj++] = 0;
                   7868:     }
1.1.1.6   root     7869: 
1.1       root     7870: #ifdef DEBUG_DISAS
1.1.1.7   root     7871:     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1.1       root     7872:         int disas_flags;
1.1.1.7   root     7873:         qemu_log("----------------\n");
                   7874:         qemu_log("IN: %s\n", lookup_symbol(pc_start));
1.1       root     7875: #ifdef TARGET_X86_64
                   7876:         if (dc->code64)
                   7877:             disas_flags = 2;
                   7878:         else
                   7879: #endif
                   7880:             disas_flags = !dc->code32;
1.1.1.7   root     7881:         log_target_disas(pc_start, pc_ptr - pc_start, disas_flags);
                   7882:         qemu_log("\n");
1.1       root     7883:     }
                   7884: #endif
                   7885: 
1.1.1.7   root     7886:     if (!search_pc) {
1.1       root     7887:         tb->size = pc_ptr - pc_start;
1.1.1.7   root     7888:         tb->icount = num_insns;
                   7889:     }
1.1       root     7890: }
                   7891: 
1.1.1.7   root     7892: void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
1.1       root     7893: {
1.1.1.7   root     7894:     gen_intermediate_code_internal(env, tb, 0);
1.1       root     7895: }
                   7896: 
1.1.1.7   root     7897: void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
1.1       root     7898: {
1.1.1.7   root     7899:     gen_intermediate_code_internal(env, tb, 1);
1.1       root     7900: }
                   7901: 
1.1.1.15  root     7902: void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
1.1.1.7   root     7903: {
                   7904:     int cc_op;
                   7905: #ifdef DEBUG_DISAS
                   7906:     if (qemu_loglevel_mask(CPU_LOG_TB_OP)) {
                   7907:         int i;
                   7908:         qemu_log("RESTORE:\n");
                   7909:         for(i = 0;i <= pc_pos; i++) {
                   7910:             if (gen_opc_instr_start[i]) {
                   7911:                 qemu_log("0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]);
                   7912:             }
                   7913:         }
1.1.1.15  root     7914:         qemu_log("pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
                   7915:                 pc_pos, gen_opc_pc[pc_pos] - tb->cs_base,
1.1.1.7   root     7916:                 (uint32_t)tb->cs_base);
                   7917:     }
                   7918: #endif
                   7919:     env->eip = gen_opc_pc[pc_pos] - tb->cs_base;
                   7920:     cc_op = gen_opc_cc_op[pc_pos];
                   7921:     if (cc_op != CC_OP_DYNAMIC)
                   7922:         env->cc_op = cc_op;
                   7923: }

unix.superglobalmegacorp.com