/[qemu]/qemu/target-i386/translate.c
ViewVC logotype

Diff of /qemu/target-i386/translate.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.37 by bellard, Thu Jan 6 20:46:58 2005 UTC revision 1.38 by bellard, Sat Jan 8 18:58:29 2005 UTC
# Line 1606  static void gen_lea_modrm(DisasContext * Line 1606  static void gen_lea_modrm(DisasContext *
1606      *offset_ptr = disp;      *offset_ptr = disp;
1607  }  }
1608    
1609    /* used for LEA and MOV AX, mem */
1610    static void gen_add_A0_ds_seg(DisasContext *s)
1611    {
1612        int override, must_add_seg;
1613        must_add_seg = s->addseg;
1614        override = R_DS;
1615        if (s->override >= 0) {
1616            override = s->override;
1617            must_add_seg = 1;
1618        } else {
1619            override = R_DS;
1620        }
1621        if (must_add_seg) {
1622            gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
1623        }
1624    }
1625    
1626  /* generate modrm memory load or store of 'reg'. TMP0 is used if reg !=  /* generate modrm memory load or store of 'reg'. TMP0 is used if reg !=
1627     OR_TMP0 */     OR_TMP0 */
1628  static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)  static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
# Line 2193  static void gen_movtl_T0_im(target_ulong Line 2210  static void gen_movtl_T0_im(target_ulong
2210  #endif  #endif
2211  }  }
2212    
2213    static GenOpFunc1 *gen_ldq_env_A0[3] = {
2214        gen_op_ldq_raw_env_A0,
2215    #ifndef CONFIG_USER_ONLY
2216        gen_op_ldq_kernel_env_A0,
2217        gen_op_ldq_user_env_A0,
2218    #endif
2219    };
2220    
2221    static GenOpFunc1 *gen_stq_env_A0[3] = {
2222        gen_op_stq_raw_env_A0,
2223    #ifndef CONFIG_USER_ONLY
2224        gen_op_stq_kernel_env_A0,
2225        gen_op_stq_user_env_A0,
2226    #endif
2227    };
2228    
2229  static GenOpFunc1 *gen_ldo_env_A0[3] = {  static GenOpFunc1 *gen_ldo_env_A0[3] = {
2230      gen_op_ldo_raw_env_A0,      gen_op_ldo_raw_env_A0,
2231  #ifndef CONFIG_USER_ONLY  #ifndef CONFIG_USER_ONLY
# Line 2209  static GenOpFunc1 *gen_sto_env_A0[3] = { Line 2242  static GenOpFunc1 *gen_sto_env_A0[3] = {
2242  #endif  #endif
2243  };  };
2244    
2245    #define SSE_SPECIAL ((GenOpFunc2 *)1)
2246    
2247    #define MMX_OP2(x) { gen_op_ ## x ## _mmx, gen_op_ ## x ## _xmm }
2248    #define SSE_FOP(x) { gen_op_ ## x ## ps, gen_op_ ## x ## pd, \
2249                         gen_op_ ## x ## ss, gen_op_ ## x ## sd, }
2250    
2251    static GenOpFunc2 *sse_op_table1[256][4] = {
2252        /* pure SSE operations */
2253        [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2254        [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2255        [0x12] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
2256        [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
2257        [0x14] = { gen_op_punpckldq_xmm, gen_op_punpcklqdq_xmm },
2258        [0x15] = { gen_op_punpckhdq_xmm, gen_op_punpckhqdq_xmm },
2259        [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */
2260        [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */
2261    
2262        [0x28] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2263        [0x29] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2264        [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2265        [0x2b] = { SSE_SPECIAL, SSE_SPECIAL },  /* movntps, movntpd */
2266        [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2267        [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2268        [0x2e] = { gen_op_ucomiss, gen_op_ucomisd },
2269        [0x2f] = { gen_op_comiss, gen_op_comisd },
2270        [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2271        [0x51] = SSE_FOP(sqrt),
2272        [0x52] = { gen_op_rsqrtps, NULL, gen_op_rsqrtss, NULL },
2273        [0x53] = { gen_op_rcpps, NULL, gen_op_rcpss, NULL },
2274        [0x54] = { gen_op_pand_xmm, gen_op_pand_xmm }, /* andps, andpd */
2275        [0x55] = { gen_op_pandn_xmm, gen_op_pandn_xmm }, /* andnps, andnpd */
2276        [0x56] = { gen_op_por_xmm, gen_op_por_xmm }, /* orps, orpd */
2277        [0x57] = { gen_op_pxor_xmm, gen_op_pxor_xmm }, /* xorps, xorpd */
2278        [0x58] = SSE_FOP(add),
2279        [0x59] = SSE_FOP(mul),
2280        [0x5a] = { gen_op_cvtps2pd, gen_op_cvtpd2ps,
2281                   gen_op_cvtss2sd, gen_op_cvtsd2ss },
2282        [0x5b] = { gen_op_cvtdq2ps, gen_op_cvtps2dq, gen_op_cvttps2dq },
2283        [0x5c] = SSE_FOP(sub),
2284        [0x5d] = SSE_FOP(min),
2285        [0x5e] = SSE_FOP(div),
2286        [0x5f] = SSE_FOP(max),
2287    
2288        [0xc2] = SSE_FOP(cmpeq),
2289        [0xc6] = { (GenOpFunc2 *)gen_op_pshufd_xmm, (GenOpFunc2 *)gen_op_shufpd },
2290    
2291        /* MMX ops and their SSE extensions */
2292        [0x60] = MMX_OP2(punpcklbw),
2293        [0x61] = MMX_OP2(punpcklwd),
2294        [0x62] = MMX_OP2(punpckldq),
2295        [0x63] = MMX_OP2(packsswb),
2296        [0x64] = MMX_OP2(pcmpgtb),
2297        [0x65] = MMX_OP2(pcmpgtw),
2298        [0x66] = MMX_OP2(pcmpgtl),
2299        [0x67] = MMX_OP2(packuswb),
2300        [0x68] = MMX_OP2(punpckhbw),
2301        [0x69] = MMX_OP2(punpckhwd),
2302        [0x6a] = MMX_OP2(punpckhdq),
2303        [0x6b] = MMX_OP2(packssdw),
2304        [0x6c] = { NULL, gen_op_punpcklqdq_xmm },
2305        [0x6d] = { NULL, gen_op_punpckhqdq_xmm },
2306        [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
2307        [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
2308        [0x70] = { (GenOpFunc2 *)gen_op_pshufw_mmx,
2309                   (GenOpFunc2 *)gen_op_pshufd_xmm,
2310                   (GenOpFunc2 *)gen_op_pshufhw_xmm,
2311                   (GenOpFunc2 *)gen_op_pshuflw_xmm },
2312        [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
2313        [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
2314        [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
2315        [0x74] = MMX_OP2(pcmpeqb),
2316        [0x75] = MMX_OP2(pcmpeqw),
2317        [0x76] = MMX_OP2(pcmpeql),
2318        [0x77] = { SSE_SPECIAL }, /* emms */
2319        [0x7c] = { NULL, gen_op_haddpd, NULL, gen_op_haddps },
2320        [0x7d] = { NULL, gen_op_hsubpd, NULL, gen_op_hsubps },
2321        [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
2322        [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
2323        [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
2324        [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
2325        [0xd0] = { NULL, gen_op_addsubpd, NULL, gen_op_addsubps },
2326        [0xd1] = MMX_OP2(psrlw),
2327        [0xd2] = MMX_OP2(psrld),
2328        [0xd3] = MMX_OP2(psrlq),
2329        [0xd4] = MMX_OP2(paddq),
2330        [0xd5] = MMX_OP2(pmullw),
2331        [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2332        [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
2333        [0xd8] = MMX_OP2(psubusb),
2334        [0xd9] = MMX_OP2(psubusw),
2335        [0xda] = MMX_OP2(pminub),
2336        [0xdb] = MMX_OP2(pand),
2337        [0xdc] = MMX_OP2(paddusb),
2338        [0xdd] = MMX_OP2(paddusw),
2339        [0xde] = MMX_OP2(pmaxub),
2340        [0xdf] = MMX_OP2(pandn),
2341        [0xe0] = MMX_OP2(pavgb),
2342        [0xe1] = MMX_OP2(psraw),
2343        [0xe2] = MMX_OP2(psrad),
2344        [0xe3] = MMX_OP2(pavgw),
2345        [0xe4] = MMX_OP2(pmulhuw),
2346        [0xe5] = MMX_OP2(pmulhw),
2347        [0xe6] = { NULL, gen_op_cvttpd2dq, gen_op_cvtdq2pd, gen_op_cvtpd2dq },
2348        [0xe7] = { SSE_SPECIAL , SSE_SPECIAL },  /* movntq, movntq */
2349        [0xe8] = MMX_OP2(psubsb),
2350        [0xe9] = MMX_OP2(psubsw),
2351        [0xea] = MMX_OP2(pminsw),
2352        [0xeb] = MMX_OP2(por),
2353        [0xec] = MMX_OP2(paddsb),
2354        [0xed] = MMX_OP2(paddsw),
2355        [0xee] = MMX_OP2(pmaxsw),
2356        [0xef] = MMX_OP2(pxor),
2357        [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu (PNI) */
2358        [0xf1] = MMX_OP2(psllw),
2359        [0xf2] = MMX_OP2(pslld),
2360        [0xf3] = MMX_OP2(psllq),
2361        [0xf4] = MMX_OP2(pmuludq),
2362        [0xf5] = MMX_OP2(pmaddwd),
2363        [0xf6] = MMX_OP2(psadbw),
2364        [0xf7] = MMX_OP2(maskmov),
2365        [0xf8] = MMX_OP2(psubb),
2366        [0xf9] = MMX_OP2(psubw),
2367        [0xfa] = MMX_OP2(psubl),
2368        [0xfb] = MMX_OP2(psubq),
2369        [0xfc] = MMX_OP2(paddb),
2370        [0xfd] = MMX_OP2(paddw),
2371        [0xfe] = MMX_OP2(paddl),
2372    };
2373    
2374    static GenOpFunc2 *sse_op_table2[3 * 8][2] = {
2375        [0 + 2] = MMX_OP2(psrlw),
2376        [0 + 4] = MMX_OP2(psraw),
2377        [0 + 6] = MMX_OP2(psllw),
2378        [8 + 2] = MMX_OP2(psrld),
2379        [8 + 4] = MMX_OP2(psrad),
2380        [8 + 6] = MMX_OP2(pslld),
2381        [16 + 2] = MMX_OP2(psrlq),
2382        [16 + 3] = { NULL, gen_op_psrldq_xmm },
2383        [16 + 6] = MMX_OP2(psllq),
2384        [16 + 7] = { NULL, gen_op_pslldq_xmm },
2385    };
2386    
2387    static GenOpFunc1 *sse_op_table3[4 * 3] = {
2388        gen_op_cvtsi2ss,
2389        gen_op_cvtsi2sd,
2390        X86_64_ONLY(gen_op_cvtsq2ss),
2391        X86_64_ONLY(gen_op_cvtsq2sd),
2392        
2393        gen_op_cvttss2si,
2394        gen_op_cvttsd2si,
2395        X86_64_ONLY(gen_op_cvttss2sq),
2396        X86_64_ONLY(gen_op_cvttsd2sq),
2397    
2398        gen_op_cvtss2si,
2399        gen_op_cvtsd2si,
2400        X86_64_ONLY(gen_op_cvtss2sq),
2401        X86_64_ONLY(gen_op_cvtsd2sq),
2402    };
2403        
2404    static GenOpFunc2 *sse_op_table4[8][4] = {
2405        SSE_FOP(cmpeq),
2406        SSE_FOP(cmplt),
2407        SSE_FOP(cmple),
2408        SSE_FOP(cmpunord),
2409        SSE_FOP(cmpneq),
2410        SSE_FOP(cmpnlt),
2411        SSE_FOP(cmpnle),
2412        SSE_FOP(cmpord),
2413    };
2414        
2415    static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
2416    {
2417        int b1, op1_offset, op2_offset, is_xmm, val, ot;
2418        int modrm, mod, rm, reg, reg_addr, offset_addr;
2419        GenOpFunc2 *sse_op2;
2420        GenOpFunc3 *sse_op3;
2421    
2422        b &= 0xff;
2423        if (s->prefix & PREFIX_DATA)
2424            b1 = 1;
2425        else if (s->prefix & PREFIX_REPZ)
2426            b1 = 2;
2427        else if (s->prefix & PREFIX_REPNZ)
2428            b1 = 3;
2429        else
2430            b1 = 0;
2431        sse_op2 = sse_op_table1[b][b1];
2432        if (!sse_op2)
2433            goto illegal_op;
2434        if (b <= 0x5f || b == 0xc6 || b == 0xc2) {
2435            is_xmm = 1;
2436        } else {
2437            if (b1 == 0) {
2438                /* MMX case */
2439                is_xmm = 0;
2440            } else {
2441                is_xmm = 1;
2442            }
2443        }
2444        /* simple MMX/SSE operation */
2445        if (s->flags & HF_TS_MASK) {
2446            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
2447            return;
2448        }
2449        if (s->flags & HF_EM_MASK) {
2450        illegal_op:
2451            gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
2452            return;
2453        }
2454        if (is_xmm && !(s->flags & HF_OSFXSR_MASK))
2455            goto illegal_op;
2456        if (b == 0x77) {
2457            /* emms */
2458            gen_op_emms();
2459            return;
2460        }
2461        /* prepare MMX state (XXX: optimize by storing fptt and fptags in
2462           the static cpu state) */
2463        if (!is_xmm) {
2464            gen_op_enter_mmx();
2465        }
2466    
2467        modrm = ldub_code(s->pc++);
2468        reg = ((modrm >> 3) & 7);
2469        if (is_xmm)
2470            reg |= rex_r;
2471        mod = (modrm >> 6) & 3;
2472        if (sse_op2 == SSE_SPECIAL) {
2473            b |= (b1 << 8);
2474            switch(b) {
2475            case 0x0e7: /* movntq */
2476                if (mod == 3)
2477                    goto illegal_op;
2478                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2479                gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
2480                break;
2481            case 0x1e7: /* movntdq */
2482            case 0x02b: /* movntps */
2483            case 0x12b: /* movntps */
2484            case 0x2f0: /* lddqu */
2485                if (mod == 3)
2486                    goto illegal_op;
2487                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2488                gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
2489                break;
2490            case 0x6e: /* movd mm, ea */
2491                gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
2492                gen_op_movl_mm_T0_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
2493                break;
2494            case 0x16e: /* movd xmm, ea */
2495                gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
2496                gen_op_movl_mm_T0_xmm(offsetof(CPUX86State,xmm_regs[reg]));
2497                break;
2498            case 0x6f: /* movq mm, ea */
2499                if (mod != 3) {
2500                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2501                    gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
2502                } else {
2503                    rm = (modrm & 7);
2504                    gen_op_movq(offsetof(CPUX86State,fpregs[reg].mmx),
2505                                offsetof(CPUX86State,fpregs[rm].mmx));
2506                }
2507                break;
2508            case 0x010: /* movups */
2509            case 0x110: /* movupd */
2510            case 0x028: /* movaps */
2511            case 0x128: /* movapd */
2512            case 0x16f: /* movdqa xmm, ea */
2513            case 0x26f: /* movdqu xmm, ea */
2514                if (mod != 3) {
2515                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2516                    gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
2517                } else {
2518                    rm = (modrm & 7) | REX_B(s);
2519                    gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
2520                                offsetof(CPUX86State,xmm_regs[rm]));
2521                }
2522                break;
2523            case 0x210: /* movss xmm, ea */
2524                if (mod != 3) {
2525                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2526                    gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
2527                    gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
2528                    gen_op_movl_T0_0();
2529                    gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
2530                    gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
2531                    gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
2532                } else {
2533                    rm = (modrm & 7) | REX_B(s);
2534                    gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
2535                                offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
2536                }
2537                break;
2538            case 0x310: /* movsd xmm, ea */
2539                if (mod != 3) {
2540                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2541                    gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2542                    gen_op_movl_T0_0();
2543                    gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
2544                    gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
2545                } else {
2546                    rm = (modrm & 7) | REX_B(s);
2547                    gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
2548                                offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
2549                }
2550                break;
2551            case 0x012: /* movlps */
2552            case 0x112: /* movlpd */
2553                if (mod != 3) {
2554                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2555                    gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2556                } else {
2557                    /* movhlps */
2558                    rm = (modrm & 7) | REX_B(s);
2559                    gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
2560                                offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
2561                }
2562                break;
2563            case 0x016: /* movhps */
2564            case 0x116: /* movhpd */
2565                if (mod != 3) {
2566                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2567                    gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
2568                } else {
2569                    /* movlhps */
2570                    rm = (modrm & 7) | REX_B(s);
2571                    gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
2572                                offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
2573                }
2574                break;
2575            case 0x216: /* movshdup */
2576                if (mod != 3) {
2577                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2578                    gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
2579                } else {
2580                    rm = (modrm & 7) | REX_B(s);
2581                    gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
2582                                offsetof(CPUX86State,xmm_regs[rm].XMM_L(1)));
2583                    gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
2584                                offsetof(CPUX86State,xmm_regs[rm].XMM_L(3)));
2585                }
2586                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
2587                            offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
2588                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
2589                            offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
2590                break;
2591            case 0x7e: /* movd ea, mm */
2592                gen_op_movl_T0_mm_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
2593                gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
2594                break;
2595            case 0x17e: /* movd ea, xmm */
2596                gen_op_movl_T0_mm_xmm(offsetof(CPUX86State,xmm_regs[reg]));
2597                gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
2598                break;
2599            case 0x27e: /* movq xmm, ea */
2600                if (mod != 3) {
2601                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2602                    gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2603                } else {
2604                    rm = (modrm & 7) | REX_B(s);
2605                    gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
2606                                offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
2607                }
2608                gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
2609                break;
2610            case 0x7f: /* movq ea, mm */
2611                if (mod != 3) {
2612                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2613                    gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
2614                } else {
2615                    rm = (modrm & 7);
2616                    gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
2617                                offsetof(CPUX86State,fpregs[reg].mmx));
2618                }
2619                break;
2620            case 0x011: /* movups */
2621            case 0x111: /* movupd */
2622            case 0x029: /* movaps */
2623            case 0x129: /* movapd */
2624            case 0x17f: /* movdqa ea, xmm */
2625            case 0x27f: /* movdqu ea, xmm */
2626                if (mod != 3) {
2627                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2628                    gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
2629                } else {
2630                    rm = (modrm & 7) | REX_B(s);
2631                    gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
2632                                offsetof(CPUX86State,xmm_regs[reg]));
2633                }
2634                break;
2635            case 0x211: /* movss ea, xmm */
2636                if (mod != 3) {
2637                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2638                    gen_op_movl_T0_env(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
2639                    gen_op_st_T0_A0[OT_LONG + s->mem_index]();
2640                } else {
2641                    rm = (modrm & 7) | REX_B(s);
2642                    gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)),
2643                                offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
2644                }
2645                break;
2646            case 0x311: /* movsd ea, xmm */
2647                if (mod != 3) {
2648                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2649                    gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2650                } else {
2651                    rm = (modrm & 7) | REX_B(s);
2652                    gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
2653                                offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2654                }
2655                break;
2656            case 0x013: /* movlps */
2657            case 0x113: /* movlpd */
2658                if (mod != 3) {
2659                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2660                    gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2661                } else {
2662                    goto illegal_op;
2663                }
2664                break;
2665            case 0x017: /* movhps */
2666            case 0x117: /* movhpd */
2667                if (mod != 3) {
2668                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2669                    gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
2670                } else {
2671                    goto illegal_op;
2672                }
2673                break;
2674            case 0x71: /* shift mm, im */
2675            case 0x72:
2676            case 0x73:
2677            case 0x171: /* shift xmm, im */
2678            case 0x172:
2679            case 0x173:
2680                val = ldub_code(s->pc++);
2681                if (is_xmm) {
2682                    gen_op_movl_T0_im(val);
2683                    gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
2684                    gen_op_movl_T0_0();
2685                    gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(1)));
2686                    op1_offset = offsetof(CPUX86State,xmm_t0);
2687                } else {
2688                    gen_op_movl_T0_im(val);
2689                    gen_op_movl_env_T0(offsetof(CPUX86State,mmx_t0.MMX_L(0)));
2690                    gen_op_movl_T0_0();
2691                    gen_op_movl_env_T0(offsetof(CPUX86State,mmx_t0.MMX_L(1)));
2692                    op1_offset = offsetof(CPUX86State,mmx_t0);
2693                }
2694                sse_op2 = sse_op_table2[((b - 1) & 3) * 8 + (((modrm >> 3)) & 7)][b1];
2695                if (!sse_op2)
2696                    goto illegal_op;
2697                if (is_xmm) {
2698                    rm = (modrm & 7) | REX_B(s);
2699                    op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
2700                } else {
2701                    rm = (modrm & 7);
2702                    op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
2703                }
2704                sse_op2(op2_offset, op1_offset);
2705                break;
2706            case 0x050: /* movmskps */
2707                gen_op_movmskps(offsetof(CPUX86State,xmm_regs[reg]));
2708                rm = (modrm & 7) | REX_B(s);
2709                gen_op_mov_reg_T0[OT_LONG][rm]();
2710                break;
2711            case 0x150: /* movmskpd */
2712                gen_op_movmskpd(offsetof(CPUX86State,xmm_regs[reg]));
2713                rm = (modrm & 7) | REX_B(s);
2714                gen_op_mov_reg_T0[OT_LONG][rm]();
2715                break;
2716            case 0x02a: /* cvtpi2ps */
2717            case 0x12a: /* cvtpi2pd */
2718                gen_op_enter_mmx();
2719                if (mod != 3) {
2720                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2721                    op2_offset = offsetof(CPUX86State,mmx_t0);
2722                    gen_ldq_env_A0[s->mem_index >> 2](op2_offset);
2723                } else {
2724                    rm = (modrm & 7);
2725                    op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
2726                }
2727                op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
2728                switch(b >> 8) {
2729                case 0x0:
2730                    gen_op_cvtpi2ps(op1_offset, op2_offset);
2731                    break;
2732                default:
2733                case 0x1:
2734                    gen_op_cvtpi2pd(op1_offset, op2_offset);
2735                    break;
2736                }
2737                break;
2738            case 0x22a: /* cvtsi2ss */
2739            case 0x32a: /* cvtsi2sd */
2740                ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
2741                gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
2742                op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
2743                sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2)](op1_offset);
2744                break;
2745            case 0x02c: /* cvttps2pi */
2746            case 0x12c: /* cvttpd2pi */
2747            case 0x02d: /* cvtps2pi */
2748            case 0x12d: /* cvtpd2pi */
2749                gen_op_enter_mmx();
2750                if (mod != 3) {
2751                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2752                    op2_offset = offsetof(CPUX86State,xmm_t0);
2753                    gen_ldo_env_A0[s->mem_index >> 2](op2_offset);
2754                } else {
2755                    rm = (modrm & 7) | REX_B(s);
2756                    op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
2757                }
2758                op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
2759                switch(b) {
2760                case 0x02c:
2761                    gen_op_cvttps2pi(op1_offset, op2_offset);
2762                    break;
2763                case 0x12c:
2764                    gen_op_cvttpd2pi(op1_offset, op2_offset);
2765                    break;
2766                case 0x02d:
2767                    gen_op_cvtps2pi(op1_offset, op2_offset);
2768                    break;
2769                case 0x12d:
2770                    gen_op_cvtpd2pi(op1_offset, op2_offset);
2771                    break;
2772                }
2773                break;
2774            case 0x22c: /* cvttss2si */
2775            case 0x32c: /* cvttsd2si */
2776            case 0x22d: /* cvtss2si */
2777            case 0x32d: /* cvtsd2si */
2778                ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
2779                op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
2780                sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2) + 4 +
2781                              (b & 1) * 4](op1_offset);
2782                gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
2783                break;
2784            case 0xc4: /* pinsrw */
2785            case 0x1c4:
2786                gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
2787                val = ldub_code(s->pc++);
2788                if (b1) {
2789                    val &= 7;
2790                    gen_op_pinsrw_xmm(offsetof(CPUX86State,xmm_regs[reg]), val);
2791                } else {
2792                    val &= 3;
2793                    gen_op_pinsrw_mmx(offsetof(CPUX86State,fpregs[reg].mmx), val);
2794                }
2795                break;
2796            case 0xc5: /* pextrw */
2797            case 0x1c5:
2798                if (mod != 3)
2799                    goto illegal_op;
2800                val = ldub_code(s->pc++);
2801                if (b1) {
2802                    val &= 7;
2803                    rm = (modrm & 7) | REX_B(s);
2804                    gen_op_pextrw_xmm(offsetof(CPUX86State,xmm_regs[rm]), val);
2805                } else {
2806                    val &= 3;
2807                    rm = (modrm & 7);
2808                    gen_op_pextrw_mmx(offsetof(CPUX86State,fpregs[rm].mmx), val);
2809                }
2810                reg = ((modrm >> 3) & 7) | rex_r;
2811                gen_op_mov_reg_T0[OT_LONG][reg]();
2812                break;
2813            case 0x1d6: /* movq ea, xmm */
2814                if (mod != 3) {
2815                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2816                    gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2817                } else {
2818                    rm = (modrm & 7) | REX_B(s);
2819                    gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
2820                                offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2821                    gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
2822                }
2823                break;
2824            case 0x2d6: /* movq2dq */
2825                gen_op_enter_mmx();
2826                rm = (modrm & 7) | REX_B(s);
2827                gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
2828                            offsetof(CPUX86State,fpregs[reg & 7].mmx));
2829                gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
2830                break;
2831            case 0x3d6: /* movdq2q */
2832                gen_op_enter_mmx();
2833                rm = (modrm & 7);
2834                gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
2835                            offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2836                break;
2837            case 0xd7: /* pmovmskb */
2838            case 0x1d7:
2839                if (mod != 3)
2840                    goto illegal_op;
2841                if (b1) {
2842                    rm = (modrm & 7) | REX_B(s);
2843                    gen_op_pmovmskb_xmm(offsetof(CPUX86State,xmm_regs[rm]));
2844                } else {
2845                    rm = (modrm & 7);
2846                    gen_op_pmovmskb_mmx(offsetof(CPUX86State,fpregs[rm].mmx));
2847                }
2848                reg = ((modrm >> 3) & 7) | rex_r;
2849                gen_op_mov_reg_T0[OT_LONG][reg]();
2850                break;
2851            default:
2852                goto illegal_op;
2853            }
2854        } else {
2855            /* generic MMX or SSE operation */
2856            if (b == 0xf7) {
2857                /* maskmov : we must prepare A0 */
2858                if (mod != 3)
2859                    goto illegal_op;
2860    #ifdef TARGET_X86_64
2861                if (CODE64(s)) {
2862                    gen_op_movq_A0_reg[R_EDI]();
2863                } else
2864    #endif
2865                {
2866                    gen_op_movl_A0_reg[R_EDI]();
2867                    if (s->aflag == 0)
2868                        gen_op_andl_A0_ffff();
2869                }
2870                gen_add_A0_ds_seg(s);
2871            }
2872            if (is_xmm) {
2873                op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
2874                if (mod != 3) {
2875                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2876                    op2_offset = offsetof(CPUX86State,xmm_t0);
2877                    if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f) ||
2878                                    b == 0xc2)) {
2879                        /* specific case for SSE single instructions */
2880                        if (b1 == 2) {
2881                            /* 32 bit access */
2882                            gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
2883                            gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
2884                        } else {
2885                            /* 64 bit access */
2886                            gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_t0.XMM_D(0)));
2887                        }
2888                    } else {
2889                        gen_ldo_env_A0[s->mem_index >> 2](op2_offset);
2890                    }
2891                } else {
2892                    rm = (modrm & 7) | REX_B(s);
2893                    op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
2894                }
2895            } else {
2896                op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
2897                if (mod != 3) {
2898                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2899                    op2_offset = offsetof(CPUX86State,mmx_t0);
2900                    gen_ldq_env_A0[s->mem_index >> 2](op2_offset);
2901                } else {
2902                    rm = (modrm & 7);
2903                    op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
2904                }
2905            }
2906            switch(b) {
2907            case 0x70: /* pshufx insn */
2908            case 0xc6: /* pshufx insn */
2909                val = ldub_code(s->pc++);
2910                sse_op3 = (GenOpFunc3 *)sse_op2;
2911                sse_op3(op1_offset, op2_offset, val);
2912                break;
2913            case 0xc2:
2914                /* compare insns */
2915                val = ldub_code(s->pc++);
2916                if (val >= 8)
2917                    goto illegal_op;
2918                sse_op2 = sse_op_table4[val][b1];
2919                sse_op2(op1_offset, op2_offset);
2920                break;
2921            default:
2922                sse_op2(op1_offset, op2_offset);
2923                break;
2924            }
2925            if (b == 0x2e || b == 0x2f) {
2926                s->cc_op = CC_OP_EFLAGS;
2927            }
2928        }
2929    }
2930    
2931    
2932  /* convert one instruction. s->is_jmp is set if the translation must  /* convert one instruction. s->is_jmp is set if the translation must
2933     be stopped. Return the next pc value */     be stopped. Return the next pc value */
2934  static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)  static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
# Line 3176  static target_ulong disas_insn(DisasCont Line 3896  static target_ulong disas_insn(DisasCont
3896                  }                  }
3897                  gen_op_movl_A0_im(offset_addr);                  gen_op_movl_A0_im(offset_addr);
3898              }              }
3899              /* handle override */              gen_add_A0_ds_seg(s);
             {  
                 int override, must_add_seg;  
                 must_add_seg = s->addseg;  
                 if (s->override >= 0) {  
                     override = s->override;  
                     must_add_seg = 1;  
                 } else {  
                     override = R_DS;  
                 }  
                 if (must_add_seg) {  
                     gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));  
                 }  
             }  
3900              if ((b & 2) == 0) {              if ((b & 2) == 0) {
3901                  gen_op_ld_T0_A0[ot + s->mem_index]();                  gen_op_ld_T0_A0[ot + s->mem_index]();
3902                  gen_op_mov_reg_T0[ot][R_EAX]();                  gen_op_mov_reg_T0[ot][R_EAX]();
# Line 3212  static target_ulong disas_insn(DisasCont Line 3919  static target_ulong disas_insn(DisasCont
3919              if (s->aflag == 0)              if (s->aflag == 0)
3920                  gen_op_andl_A0_ffff();                  gen_op_andl_A0_ffff();
3921          }          }
3922          /* handle override */          gen_add_A0_ds_seg(s);
         {  
             int override, must_add_seg;  
             must_add_seg = s->addseg;  
             override = R_DS;  
             if (s->override >= 0) {  
                 override = s->override;  
                 must_add_seg = 1;  
             } else {  
                 override = R_DS;  
             }  
             if (must_add_seg) {  
                 gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));  
             }  
         }  
3923          gen_op_ldu_T0_A0[OT_BYTE + s->mem_index]();          gen_op_ldu_T0_A0[OT_BYTE + s->mem_index]();
3924          gen_op_mov_reg_T0[OT_BYTE][R_EAX]();          gen_op_mov_reg_T0[OT_BYTE][R_EAX]();
3925          break;          break;
# Line 4827  static target_ulong disas_insn(DisasCont Line 5520  static target_ulong disas_insn(DisasCont
5520              /* nothing to do */              /* nothing to do */
5521          }          }
5522          break;          break;
     case 0x1ae:  
         modrm = ldub_code(s->pc++);  
         mod = (modrm >> 6) & 3;  
         op = (modrm >> 3) & 7;  
         switch(op) {  
         case 0: /* fxsave */  
             if (mod == 3 || !(s->cpuid_features & CPUID_FXSR))  
                 goto illegal_op;  
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);  
             gen_op_fxsave_A0((s->dflag == 2));  
             break;  
         case 1: /* fxrstor */  
             if (mod == 3 || !(s->cpuid_features & CPUID_FXSR))  
                 goto illegal_op;  
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);  
             gen_op_fxrstor_A0((s->dflag == 2));  
             break;  
         case 5: /* lfence */  
         case 6: /* mfence */  
         case 7: /* sfence */  
             if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE))  
                 goto illegal_op;  
             break;  
         default:  
             goto illegal_op;  
         }  
         break;  
5523      case 0x63: /* arpl or movslS (x86_64) */      case 0x63: /* arpl or movslS (x86_64) */
5524  #ifdef TARGET_X86_64  #ifdef TARGET_X86_64
5525          if (CODE64(s)) {          if (CODE64(s)) {
# Line 5018  static target_ulong disas_insn(DisasCont Line 5684  static target_ulong disas_insn(DisasCont
5684              gen_eob(s);              gen_eob(s);
5685          }          }
5686          break;          break;
5687      /* SSE support */      /* MMX/SSE/SSE2/PNI support */
5688      case 0x16f:      case 0x1c3: /* MOVNTI reg, mem */
5689          if (prefixes & PREFIX_DATA) {          if (!(s->cpuid_features & CPUID_SSE2))
             /* movdqa xmm1, xmm2/mem128 */  
             if (!(s->cpuid_features & CPUID_SSE))  
                 goto illegal_op;  
             modrm = ldub_code(s->pc++);  
             reg = ((modrm >> 3) & 7) | rex_r;  
             mod = (modrm >> 6) & 3;  
             if (mod != 3) {  
                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);  
                 gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));  
             } else {  
                 rm = (modrm & 7) | REX_B(s);  
                 gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),  
                             offsetof(CPUX86State,xmm_regs[rm]));  
             }  
         } else {  
5690              goto illegal_op;              goto illegal_op;
5691          }          ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
5692            modrm = ldub_code(s->pc++);
5693            mod = (modrm >> 6) & 3;
5694            if (mod == 3)
5695                goto illegal_op;
5696            reg = ((modrm >> 3) & 7) | rex_r;
5697            /* generate a generic store */
5698            gen_ldst_modrm(s, modrm, ot, reg, 1);
5699          break;          break;
5700      case 0x1e7:      case 0x1ae:
5701          if (prefixes & PREFIX_DATA) {          modrm = ldub_code(s->pc++);
5702              /* movntdq mem128, xmm1 */          mod = (modrm >> 6) & 3;
5703              if (!(s->cpuid_features & CPUID_SSE))          op = (modrm >> 3) & 7;
5704            switch(op) {
5705            case 0: /* fxsave */
5706                if (mod == 3 || !(s->cpuid_features & CPUID_FXSR))
5707                  goto illegal_op;                  goto illegal_op;
5708              modrm = ldub_code(s->pc++);              gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5709              reg = ((modrm >> 3) & 7) | rex_r;              gen_op_fxsave_A0((s->dflag == 2));
5710              mod = (modrm >> 6) & 3;              break;
5711              if (mod != 3) {          case 1: /* fxrstor */
5712                  gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);              if (mod == 3 || !(s->cpuid_features & CPUID_FXSR))
                 gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));  
             } else {  
5713                  goto illegal_op;                  goto illegal_op;
5714                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5715                gen_op_fxrstor_A0((s->dflag == 2));
5716                break;
5717            case 2: /* ldmxcsr */
5718            case 3: /* stmxcsr */
5719                if (s->flags & HF_TS_MASK) {
5720                    gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5721                    break;
5722              }              }
5723          } else {              if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
5724              goto illegal_op;                  mod == 3)
         }  
         break;  
     case 0x17f:  
         if (prefixes & PREFIX_DATA) {  
             /* movdqa xmm2/mem128, xmm1 */  
             if (!(s->cpuid_features & CPUID_SSE))  
5725                  goto illegal_op;                  goto illegal_op;
5726              modrm = ldub_code(s->pc++);              gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5727              reg = ((modrm >> 3) & 7) | rex_r;              if (op == 2) {
5728              mod = (modrm >> 6) & 3;                  gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
5729              if (mod != 3) {                  gen_op_movl_env_T0(offsetof(CPUX86State, mxcsr));
                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);  
                 gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));  
5730              } else {              } else {
5731                  rm = (modrm & 7) | REX_B(s);                  gen_op_movl_T0_env(offsetof(CPUX86State, mxcsr));
5732                  gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),                  gen_op_st_T0_A0[OT_LONG + s->mem_index]();
                             offsetof(CPUX86State,xmm_regs[reg]));  
5733              }              }
5734          } else {              break;
5735            case 5: /* lfence */
5736            case 6: /* mfence */
5737            case 7: /* sfence */
5738                if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE))
5739                    goto illegal_op;
5740                break;
5741            default:
5742              goto illegal_op;              goto illegal_op;
5743          }          }
5744          break;          break;
5745        case 0x110 ... 0x117:
5746        case 0x128 ... 0x12f:
5747        case 0x150 ... 0x177:
5748        case 0x17c ... 0x17f:
5749        case 0x1c2:
5750        case 0x1c4 ... 0x1c6:
5751        case 0x1d0 ... 0x1fe:
5752            gen_sse(s, b, pc_start, rex_r);
5753            break;
5754      default:      default:
5755          goto illegal_op;          goto illegal_op;
5756      }      }
# Line 5250  static uint16_t opc_write_flags[NB_OPS] Line 5924  static uint16_t opc_write_flags[NB_OPS]
5924      [INDEX_op_imull_T0_T1] = CC_OSZAPC,      [INDEX_op_imull_T0_T1] = CC_OSZAPC,
5925      X86_64_DEF([INDEX_op_imulq_T0_T1] = CC_OSZAPC,)      X86_64_DEF([INDEX_op_imulq_T0_T1] = CC_OSZAPC,)
5926    
5927        /* sse */
5928        [INDEX_op_ucomiss] = CC_OSZAPC,
5929        [INDEX_op_ucomisd] = CC_OSZAPC,
5930        [INDEX_op_comiss] = CC_OSZAPC,
5931        [INDEX_op_comisd] = CC_OSZAPC,
5932    
5933      /* bcd */      /* bcd */
5934      [INDEX_op_aam] = CC_OSZAPC,      [INDEX_op_aam] = CC_OSZAPC,
5935      [INDEX_op_aad] = CC_OSZAPC,      [INDEX_op_aad] = CC_OSZAPC,

Legend:
Removed from v.1.37  
changed lines
  Added in v.1.38

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26