Revision 664e0f19 target-i386/translate.c

b/target-i386/translate.c
1606 1606
    *offset_ptr = disp;
1607 1607
}
1608 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

  
1609 1626
/* generate modrm memory load or store of 'reg'. TMP0 is used if reg !=
1610 1627
   OR_TMP0 */
1611 1628
static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
......
2193 2210
#endif
2194 2211
}
2195 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

  
2196 2229
static GenOpFunc1 *gen_ldo_env_A0[3] = {
2197 2230
    gen_op_ldo_raw_env_A0,
2198 2231
#ifndef CONFIG_USER_ONLY
......
2209 2242
#endif
2210 2243
};
2211 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

  
2212 2932
/* convert one instruction. s->is_jmp is set if the translation must
2213 2933
   be stopped. Return the next pc value */
2214 2934
static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
......
3176 3896
                }
3177 3897
                gen_op_movl_A0_im(offset_addr);
3178 3898
            }
3179
            /* handle override */
3180
            {
3181
                int override, must_add_seg;
3182
                must_add_seg = s->addseg;
3183
                if (s->override >= 0) {
3184
                    override = s->override;
3185
                    must_add_seg = 1;
3186
                } else {
3187
                    override = R_DS;
3188
                }
3189
                if (must_add_seg) {
3190
                    gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
3191
                }
3192
            }
3899
            gen_add_A0_ds_seg(s);
3193 3900
            if ((b & 2) == 0) {
3194 3901
                gen_op_ld_T0_A0[ot + s->mem_index]();
3195 3902
                gen_op_mov_reg_T0[ot][R_EAX]();
......
3212 3919
            if (s->aflag == 0)
3213 3920
                gen_op_andl_A0_ffff();
3214 3921
        }
3215
        /* handle override */
3216
        {
3217
            int override, must_add_seg;
3218
            must_add_seg = s->addseg;
3219
            override = R_DS;
3220
            if (s->override >= 0) {
3221
                override = s->override;
3222
                must_add_seg = 1;
3223
            } else {
3224
                override = R_DS;
3225
            }
3226
            if (must_add_seg) {
3227
                gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
3228
            }
3229
        }
3922
        gen_add_A0_ds_seg(s);
3230 3923
        gen_op_ldu_T0_A0[OT_BYTE + s->mem_index]();
3231 3924
        gen_op_mov_reg_T0[OT_BYTE][R_EAX]();
3232 3925
        break;
......
4827 5520
            /* nothing to do */
4828 5521
        }
4829 5522
        break;
4830
    case 0x1ae:
4831
        modrm = ldub_code(s->pc++);
4832
        mod = (modrm >> 6) & 3;
4833
        op = (modrm >> 3) & 7;
4834
        switch(op) {
4835
        case 0: /* fxsave */
4836
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR))
4837
                goto illegal_op;
4838
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4839
            gen_op_fxsave_A0((s->dflag == 2));
4840
            break;
4841
        case 1: /* fxrstor */
4842
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR))
4843
                goto illegal_op;
4844
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4845
            gen_op_fxrstor_A0((s->dflag == 2));
4846
            break;
4847
        case 5: /* lfence */
4848
        case 6: /* mfence */
4849
        case 7: /* sfence */
4850
            if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE))
4851
                goto illegal_op;
4852
            break;
4853
        default:
4854
            goto illegal_op;
4855
        }
4856
        break;
4857 5523
    case 0x63: /* arpl or movslS (x86_64) */
4858 5524
#ifdef TARGET_X86_64
4859 5525
        if (CODE64(s)) {
......
5018 5684
            gen_eob(s);
5019 5685
        }
5020 5686
        break;
5021
    /* SSE support */
5022
    case 0x16f:
5023
        if (prefixes & PREFIX_DATA) {
5024
            /* movdqa xmm1, xmm2/mem128 */
5025
            if (!(s->cpuid_features & CPUID_SSE))
5026
                goto illegal_op;
5027
            modrm = ldub_code(s->pc++);
5028
            reg = ((modrm >> 3) & 7) | rex_r;
5029
            mod = (modrm >> 6) & 3;
5030
            if (mod != 3) {
5031
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5032
                gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
5033
            } else {
5034
                rm = (modrm & 7) | REX_B(s);
5035
                gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
5036
                            offsetof(CPUX86State,xmm_regs[rm]));
5037
            }
5038
        } else {
5687
    /* MMX/SSE/SSE2/PNI support */
5688
    case 0x1c3: /* MOVNTI reg, mem */
5689
        if (!(s->cpuid_features & CPUID_SSE2))
5039 5690
            goto illegal_op;
5040
        }
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);
5041 5699
        break;
5042
    case 0x1e7:
5043
        if (prefixes & PREFIX_DATA) {
5044
            /* movntdq mem128, xmm1 */
5045
            if (!(s->cpuid_features & CPUID_SSE))
5700
    case 0x1ae:
5701
        modrm = ldub_code(s->pc++);
5702
        mod = (modrm >> 6) & 3;
5703
        op = (modrm >> 3) & 7;
5704
        switch(op) {
5705
        case 0: /* fxsave */
5706
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR))
5046 5707
                goto illegal_op;
5047
            modrm = ldub_code(s->pc++);
5048
            reg = ((modrm >> 3) & 7) | rex_r;
5049
            mod = (modrm >> 6) & 3;
5050
            if (mod != 3) {
5051
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5052
                gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
5053
            } else {
5708
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5709
            gen_op_fxsave_A0((s->dflag == 2));
5710
            break;
5711
        case 1: /* fxrstor */
5712
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR))
5054 5713
                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;
5055 5722
            }
5056
        } else {
5057
            goto illegal_op;
5058
        }
5059
        break;
5060
    case 0x17f:
5061
        if (prefixes & PREFIX_DATA) {
5062
            /* movdqa xmm2/mem128, xmm1 */
5063
            if (!(s->cpuid_features & CPUID_SSE))
5723
            if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
5724
                mod == 3)
5064 5725
                goto illegal_op;
5065
            modrm = ldub_code(s->pc++);
5066
            reg = ((modrm >> 3) & 7) | rex_r;
5067
            mod = (modrm >> 6) & 3;
5068
            if (mod != 3) {
5069
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5070
                gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
5726
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5727
            if (op == 2) {
5728
                gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
5729
                gen_op_movl_env_T0(offsetof(CPUX86State, mxcsr));
5071 5730
            } else {
5072
                rm = (modrm & 7) | REX_B(s);
5073
                gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
5074
                            offsetof(CPUX86State,xmm_regs[reg]));
5731
                gen_op_movl_T0_env(offsetof(CPUX86State, mxcsr));
5732
                gen_op_st_T0_A0[OT_LONG + s->mem_index]();
5075 5733
            }
5076
        } else {
5734
            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:
5077 5742
            goto illegal_op;
5078 5743
        }
5079 5744
        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;
5080 5754
    default:
5081 5755
        goto illegal_op;
5082 5756
    }
......
5250 5924
    [INDEX_op_imull_T0_T1] = CC_OSZAPC,
5251 5925
    X86_64_DEF([INDEX_op_imulq_T0_T1] = CC_OSZAPC,)
5252 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

  
5253 5933
    /* bcd */
5254 5934
    [INDEX_op_aam] = CC_OSZAPC,
5255 5935
    [INDEX_op_aad] = CC_OSZAPC,

Also available in: Unified diff