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

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.